Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Metrics API] [Breaking] Enforce meter name, version schema_url to be static string slices #2112

Merged
7 changes: 3 additions & 4 deletions opentelemetry-sdk/src/metrics/meter_provider.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use core::fmt;
use std::{
borrow::Cow,
collections::HashMap,
sync::{
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -139,9 +138,9 @@ impl Drop for SdkMeterProviderInner {
impl MeterProvider for SdkMeterProvider {
fn versioned_meter(
&self,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
name: &'static str,
version: Option<&'static str>,
schema_url: Option<&'static str>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
if self.inner.is_shutdown.load(Ordering::Relaxed) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use std::sync::{Arc, Mutex};
/// .build();
///
/// // Create and record metrics using the MeterProvider
/// let meter = meter_provider.meter(std::borrow::Cow::Borrowed("example"));
/// let meter = meter_provider.meter("example");
/// let counter = meter.u64_counter("my_counter").init();
/// counter.add(1, &[KeyValue::new("key", "value")]);
///
Expand Down
111 changes: 14 additions & 97 deletions opentelemetry/src/global/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,13 @@
use crate::metrics::{self, Meter, MeterProvider};
use crate::KeyValue;
use core::fmt;
use once_cell::sync::Lazy;
use std::{
borrow::Cow,
sync::{Arc, RwLock},
};
use std::sync::{Arc, RwLock};

/// The global `MeterProvider` singleton.
static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> = Lazy::new(|| {
RwLock::new(GlobalMeterProvider::new(
metrics::noop::NoopMeterProvider::new(),
))
});

/// Allows a specific [MeterProvider] to be used generically by the
/// [GlobalMeterProvider] by mirroring the interface and boxing the return types.
trait ObjectSafeMeterProvider {
/// Creates a versioned named meter instance that is a trait object through the underlying
/// [MeterProvider].
fn versioned_meter_cow(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter;
}

impl<P> ObjectSafeMeterProvider for P
where
P: MeterProvider,
{
/// Return a versioned boxed tracer
fn versioned_meter_cow(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
self.versioned_meter(name, version, schema_url, attributes)
}
}
type GlobalMeterProvider = Arc<dyn MeterProvider + Send + Sync>;

/// Represents the globally configured [`MeterProvider`] instance for this
/// application.
#[derive(Clone)]
pub struct GlobalMeterProvider {
provider: Arc<dyn ObjectSafeMeterProvider + Send + Sync>,
}

impl fmt::Debug for GlobalMeterProvider {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GlobalMeterProvider").finish()
}
}

impl MeterProvider for GlobalMeterProvider {
fn versioned_meter(
&self,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
self.provider.versioned_meter_cow(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
)
}
}

impl GlobalMeterProvider {
/// Create a new global meter provider
fn new<P>(provider: P) -> Self
where
P: MeterProvider + Send + Sync + 'static,
{
GlobalMeterProvider {
provider: Arc::new(provider),
}
}
}
/// The global `MeterProvider` singleton.
static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> =
Lazy::new(|| RwLock::new(Arc::new(metrics::noop::NoopMeterProvider::new())));

/// Sets the given [`MeterProvider`] instance as the current global meter
/// provider.
Expand All @@ -95,25 +18,24 @@
let mut global_provider = GLOBAL_METER_PROVIDER
.write()
.expect("GLOBAL_METER_PROVIDER RwLock poisoned");
*global_provider = GlobalMeterProvider::new(new_provider);
*global_provider = Arc::new(new_provider);
}

/// Returns an instance of the currently configured global [`MeterProvider`]
/// through [`GlobalMeterProvider`].
/// Returns an instance of the currently configured global [`MeterProvider`].
pub fn meter_provider() -> GlobalMeterProvider {
GLOBAL_METER_PROVIDER
.read()
.expect("GLOBAL_METER_PROVIDER RwLock poisoned")
.clone()
}

/// Creates a named [`Meter`] via the configured [`GlobalMeterProvider`].
/// Creates a named [`Meter`] via the currently configured global [`MeterProvider`].
///
/// If the name is an empty string, the provider will use a default name.
///
/// This is a more convenient way of expressing `global::meter_provider().meter(name)`.
pub fn meter(name: impl Into<Cow<'static, str>>) -> Meter {
meter_provider().meter(name.into())
pub fn meter(name: &'static str) -> Meter {
meter_provider().meter(name)
}

/// Creates a [`Meter`] with the name, version and schema url.
Expand All @@ -138,15 +60,10 @@
/// );
/// ```
pub fn meter_with_version(
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
name: &'static str,
version: Option<&'static str>,
schema_url: Option<&'static str>,

Check warning on line 65 in opentelemetry/src/global/metrics.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/global/metrics.rs#L63-L65

Added lines #L63 - L65 were not covered by tests
attributes: Option<Vec<KeyValue>>,
) -> Meter {
meter_provider().versioned_meter(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
)
meter_provider().versioned_meter(name, version, schema_url, attributes)

Check warning on line 68 in opentelemetry/src/global/metrics.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/global/metrics.rs#L68

Added line #L68 was not covered by tests
}
15 changes: 5 additions & 10 deletions opentelemetry/src/metrics/meter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,8 @@ pub trait MeterProvider {
/// Some(vec![KeyValue::new("key", "value")]),
/// );
/// ```
fn meter(&self, name: impl Into<Cow<'static, str>>) -> Meter {
self.versioned_meter(
name,
None::<Cow<'static, str>>,
None::<Cow<'static, str>>,
None,
)
fn meter(&self, name: &'static str) -> Meter {
self.versioned_meter(name, None, None, None)
}

/// Returns a new versioned meter with a given name.
Expand All @@ -56,9 +51,9 @@ pub trait MeterProvider {
/// default name will be used instead.
fn versioned_meter(
&self,
name: impl Into<Cow<'static, str>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stormshield-fabs FYI. #1527 is still to be added for Metrics, which will remove versioned_meter in favor of builder pattern.

version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
name: &'static str,
version: Option<&'static str>,
schema_url: Option<&'static str>,
attributes: Option<Vec<KeyValue>>,
) -> Meter;
}
Expand Down
8 changes: 4 additions & 4 deletions opentelemetry/src/metrics/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
KeyValue,
};
use std::{any::Any, borrow::Cow, sync::Arc};
use std::{any::Any, sync::Arc};

/// A no-op instance of a `MetricProvider`
#[derive(Debug, Default)]
Expand All @@ -28,9 +28,9 @@
impl MeterProvider for NoopMeterProvider {
fn versioned_meter(
&self,
_name: impl Into<Cow<'static, str>>,
_version: Option<impl Into<Cow<'static, str>>>,
_schema_url: Option<impl Into<Cow<'static, str>>>,
_name: &'static str,
_version: Option<&'static str>,
_schema_url: Option<&'static str>,

Check warning on line 33 in opentelemetry/src/metrics/noop.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/metrics/noop.rs#L31-L33

Added lines #L31 - L33 were not covered by tests
_attributes: Option<Vec<KeyValue>>,
) -> Meter {
Meter::new(Arc::new(NoopMeterCore::new()))
Expand Down
Loading