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}