Revert "SERVER-114943 Set up and Initialize MetricsService as a Decoration on ServiceContext (#45064)" (#45143)

Co-authored-by: auto-revert-processor <devprod-si-team@mongodb.com>
GitOrigin-RevId: aa9664a25e8ebcc363f52dae35757ebcf5e21496
This commit is contained in:
auto-revert-app[bot] 2025-12-11 19:19:07 +00:00 committed by MongoDB Bot
parent 94344072b8
commit ee03d571cd
9 changed files with 37 additions and 304 deletions

View File

@ -2432,7 +2432,7 @@ mongo_cc_library(
"//src/mongo/db/ttl:ttl_collection_cache",
"//src/mongo/db/ttl:ttl_d",
"//src/mongo/db/update:update_driver",
"//src/mongo/otel/metrics:metrics_initialization",
"//src/mongo/otel/metrics:otel_metrics",
"//src/mongo/otel/traces:tracing_initialization",
"update_index_data",
] + select({

View File

@ -2002,7 +2002,7 @@ int mongod_main(int argc, char* argv[]) {
// initialize_server_global_state::forkServerOrDie) and before the creation of any other threads
startSignalProcessingThread();
uassertStatusOK(otel::metrics::initialize());
uassertStatusOK(otel::metrics::initialize("mongod"));
auto* service = [] {
try {

View File

@ -27,24 +27,7 @@ mongo_cc_unit_test(
)
mongo_cc_library(
name = "metrics_service",
srcs = [
"metrics_service.cpp",
],
deps = [
"//src/mongo/db:server_base",
] + select(
{
"@//bazel/config:build_otel_enabled": [
"//src/third_party/opentelemetry-cpp/api",
],
"//conditions:default": [],
},
),
)
mongo_cc_library(
name = "metrics_initialization",
name = "otel_metrics",
srcs = [
"metrics_initialization.cpp",
"metrics_settings_gen",
@ -72,30 +55,15 @@ mongo_cc_library(
)
mongo_cc_unit_test(
name = "metrics_initialization_test",
name = "metrics_test",
srcs = [
"metrics_initialization_test.cpp",
],
tags = ["mongo_unittest_second_group"],
tags = ["mongo_unittest_seventh_group"],
target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
deps = [
":metrics_initialization",
],
)
mongo_cc_unit_test(
name = "metrics_service_test",
srcs = [
"metrics_service_test.cpp",
],
tags = ["mongo_unittest_first_group"],
target_compatible_with = OTEL_TARGET_COMPATIBLE_WITH,
deps = [
":metrics_initialization",
":metrics_service",
"//src/mongo/db:service_context_test_fixture",
":otel_metrics",
"//src/third_party/opentelemetry-cpp/api",
"//src/third_party/opentelemetry-cpp/sdk/src/metrics",
],
)

View File

@ -57,9 +57,12 @@ namespace otlp = opentelemetry::exporter::otlp;
namespace metrics_api = opentelemetry::metrics;
namespace metrics_sdk = opentelemetry::sdk::metrics;
Status initializeHttp(const std::string& endpoint, const std::string& compression) {
Status initializeHttp(const std::string& name,
const std::string& endpoint,
const std::string& compression) {
LOGV2(10500901,
"Initializing OpenTelemetry metrics using HTTP exporter",
"name"_attr = name,
"endpoint"_attr = endpoint);
opentelemetry::exporter::otlp::OtlpHttpMetricExporterOptions hmeOpts;
@ -85,16 +88,17 @@ Status initializeHttp(const std::string& endpoint, const std::string& compressio
return Status::OK();
}
Status initializeFile(const std::string& directory) {
Status initializeFile(const std::string& name, const std::string& directory) {
LOGV2(10500902,
"Initializing OpenTelemetry metrics using file exporter",
"name"_attr = name,
"directory"_attr = directory);
auto pid = ProcessId::getCurrent().toString();
opentelemetry::exporter::otlp::OtlpFileMetricExporterOptions fmeOpts;
otlp::OtlpFileClientFileSystemOptions sysOpts;
sysOpts.file_pattern = fmt::format("{}/mongodb-{}-%Y%m%d-metrics.jsonl", directory, pid);
sysOpts.file_pattern = fmt::format("{}/{}-{}-%Y%m%d-metrics.jsonl", directory, name, pid);
fmeOpts.backend_options = sysOpts;
auto exporter = otlp::OtlpFileMetricExporterFactory::Create(fmeOpts);
@ -139,14 +143,14 @@ void validateOptions() {
}
} // namespace
Status initialize() {
Status initialize(const std::string& name) {
try {
validateOptions();
if (!gOpenTelemetryMetricsHttpEndpoint.empty()) {
return initializeHttp(gOpenTelemetryMetricsHttpEndpoint,
gOpenTelemetryMetricsCompression);
return initializeHttp(
name, gOpenTelemetryMetricsHttpEndpoint, gOpenTelemetryMetricsCompression);
} else if (!gOpenTelemetryMetricsDirectory.empty()) {
return initializeFile(gOpenTelemetryMetricsDirectory);
return initializeFile(name, gOpenTelemetryMetricsDirectory);
}
LOGV2(10500903, "Not initializing OpenTelemetry metrics");
return Status::OK();
@ -169,7 +173,7 @@ namespace mongo::otel::metrics {
/**
* Initializes OpenTelemetry metrics using either the HTTP or file exporter.
*/
Status initialize() {
Status initialize(const std::string&) {
return Status::OK();
}

View File

@ -39,7 +39,7 @@ namespace mongo::otel::metrics {
/**
* Initializes OpenTelemetry metrics using either the HTTP or file exporter.
*/
MONGO_MOD_PUBLIC Status initialize();
MONGO_MOD_PUBLIC Status initialize(const std::string& name);
/**
* Shuts down the OpenTelemetry metric export process by setting the global MeterProvider to a

View File

@ -34,7 +34,6 @@
#include "mongo/idl/server_parameter_test_controller.h"
#include "mongo/otel/metrics/metrics_initialization.h"
#include "mongo/otel/metrics/metrics_settings_gen.h"
#include "mongo/unittest/temp_dir.h"
#include "mongo/unittest/unittest.h"
#include <opentelemetry/metrics/noop.h>
@ -55,12 +54,7 @@ public:
opentelemetry::metrics::Provider::SetMeterProvider({});
}
const std::string& getMetricsPath() {
return _tempMetricsDir.path();
}
private:
unittest::TempDir _tempMetricsDir{"otel_metrics_test"};
RAIIServerParameterControllerForTest _featureFlagController{"featureFlagOtelMetrics", true};
};
@ -69,15 +63,15 @@ bool isNoop(opentelemetry::metrics::MeterProvider* provider) {
}
TEST_F(OtelMetricsInitializationTest, NoMeterProvider) {
ASSERT_OK(metrics::initialize());
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_TRUE(isNoop(provider.get()));
}
TEST_F(OtelMetricsInitializationTest, Shutdown) {
RAIIServerParameterControllerForTest param{"openTelemetryMetricsDirectory", getMetricsPath()};
ASSERT_OK(metrics::initialize());
RAIIServerParameterControllerForTest param{"openTelemetryMetricsDirectory", "/tmp/"};
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_FALSE(isNoop(provider.get()));
ASSERT_NOT_EQUALS(provider.get(), nullptr);
@ -88,8 +82,8 @@ TEST_F(OtelMetricsInitializationTest, Shutdown) {
}
TEST_F(OtelMetricsInitializationTest, FileMeterProvider) {
RAIIServerParameterControllerForTest param{"openTelemetryMetricsDirectory", getMetricsPath()};
ASSERT_OK(metrics::initialize());
RAIIServerParameterControllerForTest param{"openTelemetryMetricsDirectory", "/tmp/"};
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_FALSE(isNoop(provider.get()));
@ -98,7 +92,7 @@ TEST_F(OtelMetricsInitializationTest, FileMeterProvider) {
TEST_F(OtelMetricsInitializationTest, HttpMeterProvider) {
RAIIServerParameterControllerForTest param{"openTelemetryMetricsHttpEndpoint",
"http://localhost:4318/v1/traces"};
ASSERT_OK(metrics::initialize());
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_FALSE(isNoop(provider.get()));
@ -107,9 +101,8 @@ TEST_F(OtelMetricsInitializationTest, HttpMeterProvider) {
TEST_F(OtelMetricsInitializationTest, HttpAndDirectory) {
RAIIServerParameterControllerForTest httpParam{"openTelemetryMetricsHttpEndpoint",
"http://localhost:4318/v1/traces"};
RAIIServerParameterControllerForTest directoryParam{"openTelemetryMetricsDirectory",
getMetricsPath()};
auto status = metrics::initialize();
RAIIServerParameterControllerForTest directoryParam{"openTelemetryMetricsDirectory", "/tmp/"};
auto status = metrics::initialize("mongod");
ASSERT_FALSE(status.isOK());
ASSERT_EQ(status.codeString(), "InvalidOptions");
@ -119,7 +112,7 @@ TEST_F(OtelMetricsInitializationTest, HttpAndDirectory) {
TEST_F(OtelMetricsInitializationTest, FeatureFlagDisabledNoParams) {
RAIIServerParameterControllerForTest featureFlagController{"featureFlagOtelMetrics", false};
ASSERT_OK(metrics::initialize());
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_TRUE(isNoop(provider.get()));
@ -127,8 +120,8 @@ TEST_F(OtelMetricsInitializationTest, FeatureFlagDisabledNoParams) {
TEST_F(OtelMetricsInitializationTest, FeatureFlagDisabledDirectorySet) {
RAIIServerParameterControllerForTest featureFlagController{"featureFlagOtelMetrics", false};
RAIIServerParameterControllerForTest param{"openTelemetryMetricsDirectory", getMetricsPath()};
ASSERT_EQ(metrics::initialize().code(), ErrorCodes::InvalidOptions);
RAIIServerParameterControllerForTest param{"openTelemetryMetricsDirectory", "/tmp/"};
ASSERT_EQ(metrics::initialize("mongod").code(), ErrorCodes::InvalidOptions);
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_TRUE(isNoop(provider.get()));
}
@ -137,7 +130,7 @@ TEST_F(OtelMetricsInitializationTest, FeatureFlagDisabledHttpSet) {
RAIIServerParameterControllerForTest featureFlagController{"featureFlagOtelMetrics", false};
RAIIServerParameterControllerForTest param{"openTelemetryMetricsHttpEndpoint",
"http://localhost:4318/v1/traces"};
ASSERT_EQ(metrics::initialize().code(), ErrorCodes::InvalidOptions);
ASSERT_EQ(metrics::initialize("mongod").code(), ErrorCodes::InvalidOptions);
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_TRUE(isNoop(provider.get()));
}
@ -148,17 +141,16 @@ TEST_F(OtelMetricsInitializationTest, InvalidCompressionParam) {
"http://localhost:4318/v1/traces"};
RAIIServerParameterControllerForTest compressionParam{"openTelemetryMetricsCompression",
"foo"};
ASSERT_EQ(metrics::initialize().code(), ErrorCodes::InvalidOptions);
ASSERT_EQ(metrics::initialize("mongod").code(), ErrorCodes::InvalidOptions);
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_TRUE(isNoop(provider.get()));
}
RAIIServerParameterControllerForTest directoryParam{"openTelemetryMetricsDirectory",
getMetricsPath()};
RAIIServerParameterControllerForTest directoryParam{"openTelemetryMetricsDirectory", "/tmp/"};
for (const auto& value : {"gzip", "foo"}) {
RAIIServerParameterControllerForTest compressionParam{"openTelemetryMetricsCompression",
value};
ASSERT_EQ(metrics::initialize().code(), ErrorCodes::InvalidOptions);
ASSERT_EQ(metrics::initialize("mongod").code(), ErrorCodes::InvalidOptions);
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_TRUE(isNoop(provider.get()));
}
@ -171,7 +163,7 @@ TEST_F(OtelMetricsInitializationTest, ValidCompressionParam) {
for (const auto& value : {"gzip", "none"}) {
RAIIServerParameterControllerForTest compressionParam{"openTelemetryMetricsCompression",
value};
ASSERT_OK(metrics::initialize());
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_FALSE(isNoop(provider.get()));
@ -181,11 +173,10 @@ TEST_F(OtelMetricsInitializationTest, ValidCompressionParam) {
}
}
RAIIServerParameterControllerForTest directoryParam{"openTelemetryMetricsDirectory",
getMetricsPath()};
RAIIServerParameterControllerForTest directoryParam{"openTelemetryMetricsDirectory", "/tmp/"};
RAIIServerParameterControllerForTest compressionParam{"openTelemetryMetricsCompression",
"none"};
ASSERT_OK(metrics::initialize());
ASSERT_OK(metrics::initialize("mongod"));
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
ASSERT_FALSE(isNoop(provider.get()));

View File

@ -1,58 +0,0 @@
/**
* Copyright (C) 2025-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the Server Side Public License in all respects for
* all of the code used other than as permitted herein. If you modify file(s)
* with this exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
#include "mongo/otel/metrics/metrics_service.h"
#ifdef MONGO_CONFIG_OTEL
#include <opentelemetry/metrics/provider.h>
#endif
namespace mongo::otel::metrics {
namespace {
const auto& getMetricsService = ServiceContext::declareDecoration<MetricsService>();
} // namespace
#ifdef MONGO_CONFIG_OTEL
MetricsService::MetricsService() {
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
invariant(provider, "Attempted to get the MeterProvider after shutdown() was called");
_meter = provider->GetMeter(std::string{kMeterName});
}
#else
MetricsService::MetricsService() {}
#endif
MetricsService& MetricsService::get(ServiceContext* serviceContext) {
return getMetricsService(serviceContext);
}
} // namespace mongo::otel::metrics

View File

@ -1,69 +0,0 @@
/**
* Copyright (C) 2025-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the Server Side Public License in all respects for
* all of the code used other than as permitted herein. If you modify file(s)
* with this exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
#pragma once
#include "mongo/base/string_data.h"
#include "mongo/config.h"
#include "mongo/db/service_context.h"
#include "mongo/util/modules.h"
#include <opentelemetry/metrics/meter.h>
namespace mongo::otel::metrics {
/**
* The MetricsService is the external interface by which API consumers can create Instruments. The
* global MeterProvider must be set before ServiceContext construction to ensure that the meter can
* be properly initialized.
*/
class MONGO_MOD_PUBLIC MetricsService {
public:
static constexpr StringData kMeterName = "mongodb";
static MetricsService& get(ServiceContext*);
MetricsService();
// TODO SERVER-114945 Remove this method once we can validate meter construction succeeded via
// the Instruments it produces
opentelemetry::metrics::Meter* getMeter_forTest() const {
return _meter.get();
}
// TODO SERVER-114945 Add MetricsService::createUInt64Counter method
// TODO SERVER-114954 Implement MetricsService::createUInt64Gauge
// TODO SERVER-114955 Implement MetricsService::createDoubleGauge
// TODO SERVER-115164 Implement MetricsService::createHistogram method
private:
std::shared_ptr<opentelemetry::metrics::Meter> _meter{nullptr};
};
} // namespace mongo::otel::metrics

View File

@ -1,103 +0,0 @@
/**
* Copyright (C) 2025-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the Server Side Public License in all respects for
* all of the code used other than as permitted herein. If you modify file(s)
* with this exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
#include "mongo/otel/metrics/metrics_service.h"
#include "mongo/config.h"
#include "mongo/db/service_context_test_fixture.h"
#include "mongo/idl/server_parameter_test_controller.h"
#include "mongo/otel/metrics/metrics_initialization.h"
#include "mongo/unittest/temp_dir.h"
#include "mongo/unittest/unittest.h"
#include <opentelemetry/metrics/provider.h>
#include <opentelemetry/sdk/metrics/meter.h>
namespace mongo::otel::metrics {
namespace {
/**
* Helper class that initializes OpenTelemetry metrics before ServiceContextTest
* creates the ServiceContext. This ensures MetricsService decoration gets a real
* SDK MeterProvider instead of a NoopMeterProvider.
*/
class MetricsInitializationHelper {
public:
MetricsInitializationHelper()
: _featureFlagController("featureFlagOtelMetrics", true),
_directoryController("openTelemetryMetricsDirectory", _tempMetricsDir.path()) {
// Initialize metrics before ServiceContext is created
auto status = metrics::initialize();
invariant(status.isOK(), status.reason());
}
~MetricsInitializationHelper() {
metrics::shutdown();
}
private:
unittest::TempDir _tempMetricsDir{"otel_metrics_test"};
RAIIServerParameterControllerForTest _featureFlagController;
RAIIServerParameterControllerForTest _directoryController;
};
// MetricsInitializationHelper must come before ServiceContextTest in inheritance
// so that metrics are initialized before ServiceContext is created.
class MetricsServiceTest : public MetricsInitializationHelper, public ServiceContextTest {};
TEST_F(MetricsServiceTest, MeterIsInitialized) {
const auto& metricsService = MetricsService::get(getServiceContext());
auto* meter = metricsService.getMeter_forTest();
ASSERT_TRUE(meter);
// Cast to SDK Meter to access GetInstrumentationScope
auto* sdkMeter = dynamic_cast<opentelemetry::sdk::metrics::Meter*>(meter);
ASSERT_TRUE(sdkMeter);
const auto* scope = sdkMeter->GetInstrumentationScope();
ASSERT_TRUE(scope);
ASSERT_EQ(scope->GetName(), std::string{MetricsService::kMeterName});
}
// Assert that we create a NoopMeter if the global MeterProvider hasn't been set before
// initialization.
class MetricsServiceBadInitializationTest : public ServiceContextTest {};
bool isNoop(opentelemetry::metrics::Meter* provider) {
return !!dynamic_cast<opentelemetry::metrics::NoopMeter*>(provider);
}
TEST_F(MetricsServiceBadInitializationTest, ServiceContextInitBeforeMeterProvider) {
const auto& metricsService = MetricsService::get(getServiceContext());
auto* meter = metricsService.getMeter_forTest();
ASSERT_TRUE(isNoop(meter));
}
} // namespace
} // namespace mongo::otel::metrics