opentelemetry/metrics/
meter.rs

1use core::fmt;
2use std::borrow::Cow;
3use std::sync::Arc;
4
5use crate::metrics::{
6    AsyncInstrumentBuilder, Gauge, InstrumentBuilder, InstrumentProvider, ObservableCounter,
7    ObservableGauge, ObservableUpDownCounter, UpDownCounter,
8};
9use crate::InstrumentationScope;
10
11use super::{Counter, Histogram, HistogramBuilder};
12
13/// Provides access to named [Meter] instances, for instrumenting an application
14/// or crate.
15pub trait MeterProvider {
16    /// Returns a new [Meter] with the provided name and default configuration.
17    ///
18    /// A [Meter] should be scoped at most to a single application or crate. The
19    /// name needs to be unique so it does not collide with other names used by
20    /// an application, nor other applications.
21    ///
22    ///
23    /// # Examples
24    ///
25    /// ```
26    /// use opentelemetry::{global, metrics::MeterProvider};
27    /// use opentelemetry::KeyValue;
28    ///
29    /// let provider = global::meter_provider();
30    ///
31    /// // meter used in applications
32    /// let meter = provider.meter("my_app");
33    /// ```
34    fn meter(&self, name: &'static str) -> Meter {
35        let scope = InstrumentationScope::builder(name).build();
36        self.meter_with_scope(scope)
37    }
38
39    /// Returns a new [Meter] with the given instrumentation scope.
40    ///
41    /// # Examples
42    ///
43    /// ```
44    /// use std::sync::Arc;
45    /// use opentelemetry::InstrumentationScope;
46    /// use opentelemetry::metrics::MeterProvider;
47    /// use opentelemetry_sdk::metrics::SdkMeterProvider;
48    ///
49    /// let provider = SdkMeterProvider::default();
50    ///
51    /// // meter used in applications/binaries
52    /// let meter = provider.meter("my_app");
53    ///
54    /// // meter used in libraries/crates that optionally includes version and schema url
55    /// let scope = InstrumentationScope::builder(env!("CARGO_PKG_NAME"))
56    ///     .with_version(env!("CARGO_PKG_VERSION"))
57    ///     .with_schema_url("https://opentelemetry.io/schema/1.0.0")
58    ///     .build();
59    ///
60    /// let meter = provider.meter_with_scope(scope);
61    /// ```
62    fn meter_with_scope(&self, scope: InstrumentationScope) -> Meter;
63}
64
65/// Provides the ability to create instruments for recording measurements or
66/// accepting callbacks to report measurements.
67///
68/// # Instrument Types
69///
70/// Instruments are categorized as either synchronous or asynchronous:
71///
72/// - **Synchronous Instruments** (e.g., Counter): These are used inline with
73///   your application's processing logic. For example, you might use a Counter
74///   to record the number of HTTP requests received.
75///
76/// - **Asynchronous Instruments** (e.g., ObservableGauge): These allow you to
77///   register a callback function that is invoked during export. For instance,
78///   you could use an asynchronous gauge to monitor temperature from a sensor
79///   every time metrics are exported.
80///
81/// # Example Usage
82///
83/// ```rust
84/// use opentelemetry::{global, KeyValue};
85///
86/// let meter = global::meter("my-meter");
87///
88/// // Synchronous Instruments
89///
90/// // u64 Counter
91/// let u64_counter = meter.u64_counter("my_u64_counter").build();
92/// u64_counter.add(
93///     10,
94///     &[
95///         KeyValue::new("mykey1", "myvalue1"),
96///         KeyValue::new("mykey2", "myvalue2"),
97///     ],
98/// );
99///
100/// // f64 Counter
101/// let f64_counter = meter.f64_counter("my_f64_counter").build();
102/// f64_counter.add(
103///     3.15,
104///     &[
105///         KeyValue::new("mykey1", "myvalue1"),
106///         KeyValue::new("mykey2", "myvalue2"),
107///     ],
108/// );
109///
110///
111/// // u64 Observable Counter
112/// let _observable_u64_counter = meter
113///     .u64_observable_counter("my_observable_u64_counter")
114///     .with_description("My observable counter example")
115///     .with_unit("myunit")
116///     .with_callback(|observer| {
117///         observer.observe(
118///             100,
119///             &[
120///                 KeyValue::new("mykey1", "myvalue1"),
121///                 KeyValue::new("mykey2", "myvalue2"),
122///             ],
123///         )
124///     })
125///     .build();
126///
127/// // f64 Observable Counter
128/// let _observable_f64_counter = meter
129///     .f64_observable_counter("my_observable_f64_counter")
130///     .with_description("My observable counter example")
131///     .with_unit("myunit")
132///     .with_callback(|observer| {
133///         observer.observe(
134///             100.0,
135///             &[
136///                 KeyValue::new("mykey1", "myvalue1"),
137///                 KeyValue::new("mykey2", "myvalue2"),
138///             ],
139///         )
140///     })
141///     .build();
142///
143/// // i64 UpDownCounter
144/// let updown_i64_counter = meter.i64_up_down_counter("my_updown_i64_counter").build();
145/// updown_i64_counter.add(
146///     -10,
147///     &[
148///         KeyValue::new("mykey1", "myvalue1"),
149///         KeyValue::new("mykey2", "myvalue2"),
150///     ],
151/// );
152///
153/// // f64 UpDownCounter
154/// let updown_f64_counter = meter.f64_up_down_counter("my_updown_f64_counter").build();
155/// updown_f64_counter.add(
156///     -10.67,
157///     &[
158///         KeyValue::new("mykey1", "myvalue1"),
159///         KeyValue::new("mykey2", "myvalue2"),
160///     ],
161/// );
162///
163/// // i64 Observable UpDownCounter
164/// let _observable_updown_i64_counter = meter
165///     .i64_observable_up_down_counter("my_observable_i64_updown_counter")
166///     .with_description("My observable updown counter example")
167///     .with_unit("myunit")
168///     .with_callback(|observer| {
169///         observer.observe(
170///             100,
171///             &[
172///                 KeyValue::new("mykey1", "myvalue1"),
173///                 KeyValue::new("mykey2", "myvalue2"),
174///             ],
175///         )
176///     })
177///     .build();
178///
179/// // f64 Observable UpDownCounter
180/// let _observable_updown_f64_counter = meter
181///     .f64_observable_up_down_counter("my_observable_f64_updown_counter")
182///     .with_description("My observable updown counter example")
183///     .with_unit("myunit")
184///     .with_callback(|observer| {
185///         observer.observe(
186///             100.0,
187///             &[
188///                 KeyValue::new("mykey1", "myvalue1"),
189///                 KeyValue::new("mykey2", "myvalue2"),
190///             ],
191///         )
192///     })
193///     .build();
194///
195/// // i64 Gauge
196/// let gauge = meter.i64_gauge("my_gauge").build();
197/// gauge.record(
198/// -10,
199/// &[
200///     KeyValue::new("mykey1", "myvalue1"),
201///     KeyValue::new("mykey2", "myvalue2"),
202/// ],
203/// );
204///
205/// // u64 Gauge
206/// let gauge = meter.u64_gauge("my_gauge").build();
207/// gauge.record(
208/// 101,
209/// &[
210///     KeyValue::new("mykey1", "myvalue1"),
211///     KeyValue::new("mykey2", "myvalue2"),
212/// ],
213/// );
214///
215/// // f64 Gauge
216/// let gauge = meter.f64_gauge("my_gauge").build();
217/// gauge.record(
218/// 12.5,
219/// &[
220///     KeyValue::new("mykey1", "myvalue1"),
221///     KeyValue::new("mykey2", "myvalue2"),
222/// ],
223/// );
224///
225/// // u64 Observable Gauge
226/// let _observable_u64_gauge = meter
227///     .u64_observable_gauge("my_u64_gauge")
228///     .with_description("An observable gauge set to 1")
229///     .with_unit("myunit")
230///     .with_callback(|observer| {
231///         observer.observe(
232///             1,
233///             &[
234///                 KeyValue::new("mykey1", "myvalue1"),
235///                 KeyValue::new("mykey2", "myvalue2"),
236///             ],
237///         )
238///     })
239///     .build();
240///
241/// // f64 Observable Gauge
242/// let _observable_f64_gauge = meter
243///     .f64_observable_gauge("my_f64_gauge")
244///     .with_description("An observable gauge set to 1.0")
245///     .with_unit("myunit")
246///     .with_callback(|observer| {
247///         observer.observe(
248///             1.0,
249///             &[
250///                 KeyValue::new("mykey1", "myvalue1"),
251///                 KeyValue::new("mykey2", "myvalue2"),
252///             ],
253///         )
254///     })
255///     .build();
256///
257/// // i64 Observable Gauge
258/// let _observable_i64_gauge = meter
259///     .i64_observable_gauge("my_i64_gauge")
260///     .with_description("An observable gauge set to 1")
261///     .with_unit("myunit")
262///     .with_callback(|observer| {
263///         observer.observe(
264///             1,
265///             &[
266///                 KeyValue::new("mykey1", "myvalue1"),
267///                 KeyValue::new("mykey2", "myvalue2"),
268///             ],
269///         )
270///     })
271///     .build();
272///
273/// // f64 Histogram
274/// let f64_histogram = meter.f64_histogram("my_f64_histogram").build();
275/// f64_histogram.record(
276///     10.5,
277///     &[
278///         KeyValue::new("mykey1", "myvalue1"),
279///         KeyValue::new("mykey2", "myvalue2"),
280///     ],
281/// );
282///
283/// // u64 Histogram
284/// let u64_histogram = meter.u64_histogram("my_u64_histogram").build();
285/// u64_histogram.record(
286///     12,
287///     &[
288///         KeyValue::new("mykey1", "myvalue1"),
289///         KeyValue::new("mykey2", "myvalue2"),
290///     ],
291/// );
292/// ```
293///
294#[derive(Clone)]
295#[non_exhaustive]
296pub struct Meter {
297    pub(crate) instrument_provider: Arc<dyn InstrumentProvider + Send + Sync>,
298}
299
300impl Meter {
301    /// Create a new named meter from an instrumentation provider
302    #[doc(hidden)]
303    pub fn new(instrument_provider: Arc<dyn InstrumentProvider + Send + Sync>) -> Self {
304        Meter {
305            instrument_provider,
306        }
307    }
308
309    /// creates an instrument builder for recording increasing values.
310    ///
311    /// [`Counter`] can be cloned to create multiple handles to the same instrument. If a [`Counter`] needs to be shared,
312    /// users are recommended to clone the [`Counter`] instead of creating duplicate [`Counter`]s for the same metric. Creating
313    /// duplicate [`Counter`]s for the same metric could lower SDK performance.
314    pub fn u64_counter(
315        &self,
316        name: impl Into<Cow<'static, str>>,
317    ) -> InstrumentBuilder<'_, Counter<u64>> {
318        InstrumentBuilder::new(self, name.into())
319    }
320
321    /// creates an instrument builder for recording increasing values.
322    ///
323    /// [`Counter`] can be cloned to create multiple handles to the same instrument. If a [`Counter`] needs to be shared,
324    /// users are recommended to clone the [`Counter`] instead of creating duplicate [`Counter`]s for the same metric. Creating
325    /// duplicate [`Counter`]s for the same metric could lower SDK performance.
326    pub fn f64_counter(
327        &self,
328        name: impl Into<Cow<'static, str>>,
329    ) -> InstrumentBuilder<'_, Counter<f64>> {
330        InstrumentBuilder::new(self, name.into())
331    }
332
333    /// creates an instrument builder for recording increasing values via callback.
334    pub fn u64_observable_counter(
335        &self,
336        name: impl Into<Cow<'static, str>>,
337    ) -> AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64> {
338        AsyncInstrumentBuilder::new(self, name.into())
339    }
340
341    /// creates an instrument builder for recording increasing values via callback.
342    pub fn f64_observable_counter(
343        &self,
344        name: impl Into<Cow<'static, str>>,
345    ) -> AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64> {
346        AsyncInstrumentBuilder::new(self, name.into())
347    }
348
349    /// creates an instrument builder for recording changes of a value.
350    ///
351    /// [`UpDownCounter`] can be cloned to create multiple handles to the same instrument. If a [`UpDownCounter`] needs to be shared,
352    /// users are recommended to clone the [`UpDownCounter`] instead of creating duplicate [`UpDownCounter`]s for the same metric. Creating
353    /// duplicate [`UpDownCounter`]s for the same metric could lower SDK performance.
354    pub fn i64_up_down_counter(
355        &self,
356        name: impl Into<Cow<'static, str>>,
357    ) -> InstrumentBuilder<'_, UpDownCounter<i64>> {
358        InstrumentBuilder::new(self, name.into())
359    }
360
361    /// creates an instrument builder for recording changes of a value.
362    ///
363    /// [`UpDownCounter`] can be cloned to create multiple handles to the same instrument. If a [`UpDownCounter`] needs to be shared,
364    /// users are recommended to clone the [`UpDownCounter`] instead of creating duplicate [`UpDownCounter`]s for the same metric. Creating
365    /// duplicate [`UpDownCounter`]s for the same metric could lower SDK performance.
366    pub fn f64_up_down_counter(
367        &self,
368        name: impl Into<Cow<'static, str>>,
369    ) -> InstrumentBuilder<'_, UpDownCounter<f64>> {
370        InstrumentBuilder::new(self, name.into())
371    }
372
373    /// creates an instrument builder for recording changes of a value via callback.
374    ///
375    /// [`UpDownCounter`] can be cloned to create multiple handles to the same instrument. If a [`UpDownCounter`] needs to be shared,
376    /// users are recommended to clone the [`UpDownCounter`] instead of creating duplicate [`UpDownCounter`]s for the same metric. Creating
377    /// duplicate [`UpDownCounter`]s for the same metric could lower SDK performance.
378    pub fn i64_observable_up_down_counter(
379        &self,
380        name: impl Into<Cow<'static, str>>,
381    ) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<i64>, i64> {
382        AsyncInstrumentBuilder::new(self, name.into())
383    }
384
385    /// creates an instrument builder for recording changes of a value via callback.
386    pub fn f64_observable_up_down_counter(
387        &self,
388        name: impl Into<Cow<'static, str>>,
389    ) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<f64>, f64> {
390        AsyncInstrumentBuilder::new(self, name.into())
391    }
392
393    /// creates an instrument builder for recording independent values.
394    ///
395    /// [`Gauge`] can be cloned to create multiple handles to the same instrument. If a [`Gauge`] needs to be shared,
396    /// users are recommended to clone the [`Gauge`] instead of creating duplicate [`Gauge`]s for the same metric. Creating
397    /// duplicate [`Gauge`]s for the same metric could lower SDK performance.
398    pub fn u64_gauge(
399        &self,
400        name: impl Into<Cow<'static, str>>,
401    ) -> InstrumentBuilder<'_, Gauge<u64>> {
402        InstrumentBuilder::new(self, name.into())
403    }
404
405    /// creates an instrument builder for recording independent values.
406    ///
407    /// [`Gauge`] can be cloned to create multiple handles to the same instrument. If a [`Gauge`] needs to be shared,
408    /// users are recommended to clone the [`Gauge`] instead of creating duplicate [`Gauge`]s for the same metric. Creating
409    /// duplicate [`Gauge`]s for the same metric could lower SDK performance.
410    pub fn f64_gauge(
411        &self,
412        name: impl Into<Cow<'static, str>>,
413    ) -> InstrumentBuilder<'_, Gauge<f64>> {
414        InstrumentBuilder::new(self, name.into())
415    }
416
417    /// creates an instrument builder for recording independent values.
418    /// [`Gauge`] can be cloned to create multiple handles to the same instrument. If a [`Gauge`] needs to be shared,
419    /// users are recommended to clone the [`Gauge`] instead of creating duplicate [`Gauge`]s for the same metric. Creating
420    /// duplicate [`Gauge`]s for the same metric could lower SDK performance.
421    pub fn i64_gauge(
422        &self,
423        name: impl Into<Cow<'static, str>>,
424    ) -> InstrumentBuilder<'_, Gauge<i64>> {
425        InstrumentBuilder::new(self, name.into())
426    }
427
428    /// creates an instrument builder for recording the current value via callback.
429    pub fn u64_observable_gauge(
430        &self,
431        name: impl Into<Cow<'static, str>>,
432    ) -> AsyncInstrumentBuilder<'_, ObservableGauge<u64>, u64> {
433        AsyncInstrumentBuilder::new(self, name.into())
434    }
435
436    /// creates an instrument builder for recording the current value via callback.
437    pub fn i64_observable_gauge(
438        &self,
439        name: impl Into<Cow<'static, str>>,
440    ) -> AsyncInstrumentBuilder<'_, ObservableGauge<i64>, i64> {
441        AsyncInstrumentBuilder::new(self, name.into())
442    }
443
444    /// creates an instrument builder for recording the current value via callback.
445    pub fn f64_observable_gauge(
446        &self,
447        name: impl Into<Cow<'static, str>>,
448    ) -> AsyncInstrumentBuilder<'_, ObservableGauge<f64>, f64> {
449        AsyncInstrumentBuilder::new(self, name.into())
450    }
451
452    /// creates an instrument builder for recording a distribution of values.
453    ///
454    /// [`Histogram`] can be cloned to create multiple handles to the same instrument. If a [`Histogram`] needs to be shared,
455    /// users are recommended to clone the [`Histogram`] instead of creating duplicate [`Histogram`]s for the same metric. Creating
456    /// duplicate [`Histogram`]s for the same metric could lower SDK performance.
457    pub fn f64_histogram(
458        &self,
459        name: impl Into<Cow<'static, str>>,
460    ) -> HistogramBuilder<'_, Histogram<f64>> {
461        HistogramBuilder::new(self, name.into())
462    }
463
464    /// creates an instrument builder for recording a distribution of values.
465    ///
466    /// [`Histogram`] can be cloned to create multiple handles to the same instrument. If a [`Histogram`] needs to be shared,
467    /// users are recommended to clone the [`Histogram`] instead of creating duplicate [`Histogram`]s for the same metric. Creating
468    /// duplicate [`Histogram`]s for the same metric could lower SDK performance.
469    pub fn u64_histogram(
470        &self,
471        name: impl Into<Cow<'static, str>>,
472    ) -> HistogramBuilder<'_, Histogram<u64>> {
473        HistogramBuilder::new(self, name.into())
474    }
475}
476
477impl fmt::Debug for Meter {
478    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
479        f.write_str("Meter")
480    }
481}