Skip to content

Commit

Permalink
[Breaking] Enforce meter name, version schema_url to be static string…
Browse files Browse the repository at this point in the history
… slices (#2112)

Co-authored-by: Cijo Thomas <[email protected]>
Co-authored-by: Lalit Kumar Bhasin <[email protected]>
Co-authored-by: Zhongyang Wu <[email protected]>
  • Loading branch information
4 people authored Sep 17, 2024
1 parent d0a4fd0 commit 3976f3d
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 116 deletions.
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 @@ where
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(name: impl Into<Cow<'static, str>>) -> Meter {
/// );
/// ```
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>,
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)
}
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>>,
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 @@ use crate::{
},
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 NoopMeterProvider {
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>,
_attributes: Option<Vec<KeyValue>>,
) -> Meter {
Meter::new(Arc::new(NoopMeterCore::new()))
Expand Down

0 comments on commit 3976f3d

Please sign in to comment.