SERVER-123547: Move some templated code to the header (#52287)

GitOrigin-RevId: 1b92c53728f904f0a60ba14381cfd72cc218e78f
This commit is contained in:
Mike Nugent 2026-04-22 11:38:50 -04:00 committed by MongoDB Bot
parent 2d3d2c1e4a
commit b8b4646792
2 changed files with 118 additions and 115 deletions

View File

@ -46,20 +46,10 @@
namespace mongo::otel::metrics {
#ifdef MONGO_CONFIG_OTEL
namespace {
using metrics_service_detail::makeObservableInstrument;
using metrics_service_detail::observableCallback;
// Static callback function for metric types that are observable.
template <template <typename> class MetricT, typename ValueT>
void observableCallback(opentelemetry::metrics::ObserverResult observer_result, void* state) {
invariant(state != nullptr);
auto* const metric = static_cast<MetricT<ValueT>*>(state);
auto observer = std::get_if<std::shared_ptr<opentelemetry::metrics::ObserverResultT<ValueT>>>(
&observer_result);
invariant(observer != nullptr && *observer != nullptr);
for (const auto& entry : metric->values()) {
(*observer)->Observe(entry.value, entry.attributes);
}
}
namespace {
// Creates a view with the provided aggregation type and aggregation configuration.
void createView(WithLock,
@ -104,86 +94,6 @@ void createAndRegisterHistogramView(WithLock lock,
std::move(aggregationConfig));
}
template <typename T>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument> makeObservableInstrument(
opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit);
template <>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<ObservableCounter<int64_t>>(
opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateInt64ObservableCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<ObservableCounter<double>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateDoubleObservableCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<UpDownCounter<int64_t>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateInt64ObservableUpDownCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<UpDownCounter<double>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateDoubleObservableUpDownCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<Gauge<int64_t>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateInt64ObservableGauge(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<Gauge<double>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateDoubleObservableGauge(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <typename T>
std::unique_ptr<T> makeHistogram(WithLock lock,
opentelemetry::metrics::MeterProvider& provider,
@ -304,28 +214,6 @@ void MetricsService::initialize(opentelemetry::metrics::MeterProvider& provider)
}
#endif // MONGO_CONFIG_OTEL
#ifdef MONGO_CONFIG_OTEL
template <template <typename> class MetricT, typename T>
void MetricsService::_addObservable(WithLock,
const std::string& nameStr,
MetricT<T>* metricPtr,
std::string description,
MetricUnit unit) {
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
auto observable = makeObservableInstrument<MetricT<T>>(*provider, nameStr, description, unit);
tassert(ErrorCodes::InternalError,
fmt::format("Could not create observable instrument for metric: {}", nameStr),
observable != nullptr);
observable->AddCallback(observableCallback<MetricT, T>, metricPtr);
_observableInstruments.push_back(std::move(observable));
}
template void MetricsService::_addObservable<ObservableCounter, int64_t>(
WithLock, const std::string&, ObservableCounter<int64_t>*, std::string, MetricUnit);
template void MetricsService::_addObservable<ObservableCounter, double>(
WithLock, const std::string&, ObservableCounter<double>*, std::string, MetricUnit);
#endif // MONGO_CONFIG_OTEL
void MetricsService::_registerServerStatusTree(
WithLock, Metric* metricPtr, const boost::optional<ServerStatusOptions>& serverStatusOptions) {
if (!serverStatusOptions.has_value()) {

View File

@ -519,4 +519,119 @@ Counter<double, AttributeTs...>& MetricsService::createDoubleCounter(
return _createCounter<double, AttributeTs...>(
name, std::move(description), unit, defs..., options);
}
#ifdef MONGO_CONFIG_OTEL
namespace metrics_service_detail {
template <template <typename> class MetricT, typename ValueT>
MONGO_MOD_FILE_PRIVATE void observableCallback(
opentelemetry::metrics::ObserverResult observer_result, void* state) {
invariant(state != nullptr);
auto* const metric = static_cast<MetricT<ValueT>*>(state);
auto observer = std::get_if<std::shared_ptr<opentelemetry::metrics::ObserverResultT<ValueT>>>(
&observer_result);
invariant(observer != nullptr && *observer != nullptr);
for (const auto& entry : metric->values()) {
(*observer)->Observe(entry.value, entry.attributes);
}
}
template <typename T>
MONGO_MOD_FILE_PRIVATE std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit);
template <>
MONGO_MOD_FILE_PRIVATE inline std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<ObservableCounter<int64_t>>(
opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateInt64ObservableCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
MONGO_MOD_FILE_PRIVATE inline std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<ObservableCounter<double>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateDoubleObservableCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
MONGO_MOD_FILE_PRIVATE inline std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<UpDownCounter<int64_t>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateInt64ObservableUpDownCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
MONGO_MOD_FILE_PRIVATE inline std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<UpDownCounter<double>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateDoubleObservableUpDownCounter(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
MONGO_MOD_FILE_PRIVATE inline std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<Gauge<int64_t>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateInt64ObservableGauge(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
template <>
MONGO_MOD_FILE_PRIVATE inline std::shared_ptr<opentelemetry::metrics::ObservableInstrument>
makeObservableInstrument<Gauge<double>>(opentelemetry::metrics::MeterProvider& provider,
std::string name,
std::string description,
MetricUnit unit) {
return provider.GetMeter(std::string{MetricsService::kMeterName})
->CreateDoubleObservableGauge(toStdStringViewForInterop(name),
description,
toStdStringViewForInterop(toString(unit)));
}
} // namespace metrics_service_detail
template <template <typename> class MetricT, typename T>
void MetricsService::_addObservable(WithLock,
const std::string& nameStr,
MetricT<T>* metricPtr,
std::string description,
MetricUnit unit) {
auto provider = opentelemetry::metrics::Provider::GetMeterProvider();
auto observable = metrics_service_detail::makeObservableInstrument<MetricT<T>>(
*provider, nameStr, description, unit);
tassert(ErrorCodes::InternalError,
fmt::format("Could not create observable instrument for metric: {}", nameStr),
observable != nullptr);
observable->AddCallback(metrics_service_detail::observableCallback<MetricT, T>, metricPtr);
_observableInstruments.push_back(std::move(observable));
}
#endif // MONGO_CONFIG_OTEL
} // namespace mongo::otel::metrics