opentelemetry/global/
metrics.rs1use crate::metrics::{self, Meter, MeterProvider};
2use crate::KeyValue;
3use core::fmt;
4use once_cell::sync::Lazy;
5use std::{
6 borrow::Cow,
7 sync::{Arc, RwLock},
8};
9
10static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> = Lazy::new(|| {
12 RwLock::new(GlobalMeterProvider::new(
13 metrics::noop::NoopMeterProvider::new(),
14 ))
15});
16
17pub trait ObjectSafeMeterProvider {
20 fn versioned_meter_cow(
23 &self,
24 name: Cow<'static, str>,
25 version: Option<Cow<'static, str>>,
26 schema_url: Option<Cow<'static, str>>,
27 attributes: Option<Vec<KeyValue>>,
28 ) -> Meter;
29}
30
31impl<P> ObjectSafeMeterProvider for P
32where
33 P: MeterProvider,
34{
35 fn versioned_meter_cow(
37 &self,
38 name: Cow<'static, str>,
39 version: Option<Cow<'static, str>>,
40 schema_url: Option<Cow<'static, str>>,
41 attributes: Option<Vec<KeyValue>>,
42 ) -> Meter {
43 self.versioned_meter(name, version, schema_url, attributes)
44 }
45}
46
47#[derive(Clone)]
50pub struct GlobalMeterProvider {
51 provider: Arc<dyn ObjectSafeMeterProvider + Send + Sync>,
52}
53
54impl fmt::Debug for GlobalMeterProvider {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 f.debug_struct("GlobalMeterProvider").finish()
57 }
58}
59
60impl MeterProvider for GlobalMeterProvider {
61 fn versioned_meter(
62 &self,
63 name: impl Into<Cow<'static, str>>,
64 version: Option<impl Into<Cow<'static, str>>>,
65 schema_url: Option<impl Into<Cow<'static, str>>>,
66 attributes: Option<Vec<KeyValue>>,
67 ) -> Meter {
68 self.provider.versioned_meter_cow(
69 name.into(),
70 version.map(Into::into),
71 schema_url.map(Into::into),
72 attributes,
73 )
74 }
75}
76
77impl GlobalMeterProvider {
78 pub fn new<P>(provider: P) -> Self
80 where
81 P: MeterProvider + Send + Sync + 'static,
82 {
83 GlobalMeterProvider {
84 provider: Arc::new(provider),
85 }
86 }
87}
88
89pub fn set_meter_provider<P>(new_provider: P)
92where
93 P: metrics::MeterProvider + Send + Sync + 'static,
94{
95 let mut global_provider = GLOBAL_METER_PROVIDER
96 .write()
97 .expect("GLOBAL_METER_PROVIDER RwLock poisoned");
98 *global_provider = GlobalMeterProvider::new(new_provider);
99}
100
101pub fn meter_provider() -> GlobalMeterProvider {
104 GLOBAL_METER_PROVIDER
105 .read()
106 .expect("GLOBAL_METER_PROVIDER RwLock poisoned")
107 .clone()
108}
109
110pub fn meter(name: impl Into<Cow<'static, str>>) -> Meter {
116 meter_provider().meter(name.into())
117}
118
119pub fn meter_with_version(
141 name: impl Into<Cow<'static, str>>,
142 version: Option<impl Into<Cow<'static, str>>>,
143 schema_url: Option<impl Into<Cow<'static, str>>>,
144 attributes: Option<Vec<KeyValue>>,
145) -> Meter {
146 meter_provider().versioned_meter(
147 name.into(),
148 version.map(Into::into),
149 schema_url.map(Into::into),
150 attributes,
151 )
152}