diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index efdbe4a960..5a5e49b80c 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixed - Fix metric export corruption if gauges have not received a last value. (#1363) +- Return consistent `Meter` for a given scope from `MeterProvider`. (#1351) ## v0.21.0 diff --git a/opentelemetry-sdk/src/metrics/meter_provider.rs b/opentelemetry-sdk/src/metrics/meter_provider.rs index 9492cef76c..6aeed9a8c8 100644 --- a/opentelemetry-sdk/src/metrics/meter_provider.rs +++ b/opentelemetry-sdk/src/metrics/meter_provider.rs @@ -1,14 +1,15 @@ use core::fmt; use std::{ borrow::Cow, + collections::HashMap, sync::{ atomic::{AtomicBool, Ordering}, - Arc, + Arc, Mutex, }, }; use opentelemetry::{ - metrics::{noop::NoopMeterCore, InstrumentProvider, Meter as ApiMeter, MetricsError, Result}, + metrics::{noop::NoopMeterCore, Meter as ApiMeter, MetricsError, Result}, KeyValue, }; @@ -26,6 +27,7 @@ use super::{meter::Meter as SdkMeter, pipeline::Pipelines, reader::MetricReader, #[derive(Clone, Debug)] pub struct MeterProvider { pipes: Arc, + meters: Arc>>>, is_shutdown: Arc, } @@ -121,15 +123,23 @@ impl opentelemetry::metrics::MeterProvider for MeterProvider { schema_url: Option>>, attributes: Option>, ) -> ApiMeter { - let inst_provider: Arc = - if !self.is_shutdown.load(Ordering::Relaxed) { - let scope = Scope::new(name, version, schema_url, attributes); - Arc::new(SdkMeter::new(scope, self.pipes.clone())) - } else { - Arc::new(NoopMeterCore::new()) - }; + if self.is_shutdown.load(Ordering::Relaxed) { + return ApiMeter::new(Arc::new(NoopMeterCore::new())); + } + + let scope = Scope::new(name, version, schema_url, attributes); - ApiMeter::new(inst_provider) + if let Ok(mut meters) = self.meters.lock() { + let meter = meters + .entry(scope) + .or_insert_with_key(|scope| { + Arc::new(SdkMeter::new(scope.clone(), self.pipes.clone())) + }) + .clone(); + ApiMeter::new(meter) + } else { + ApiMeter::new(Arc::new(NoopMeterCore::new())) + } } } @@ -184,6 +194,7 @@ impl MeterProviderBuilder { self.readers, self.views, )), + meters: Default::default(), is_shutdown: Arc::new(AtomicBool::new(false)), } }