opentelemetry/metrics/meter.rs
1use core::fmt;
2use std::any::Any;
3use std::borrow::Cow;
4use std::sync::Arc;
5
6use crate::metrics::{
7 AsyncInstrumentBuilder, Counter, Gauge, Histogram, InstrumentBuilder, InstrumentProvider,
8 ObservableCounter, ObservableGauge, ObservableUpDownCounter, Result, UpDownCounter,
9};
10use crate::KeyValue;
11
12use super::AsyncInstrument;
13
14/// Provides access to named [Meter] instances, for instrumenting an application
15/// or crate.
16pub trait MeterProvider {
17 /// Returns a new [Meter] with the provided name and default configuration.
18 ///
19 /// A [Meter] should be scoped at most to a single application or crate. The
20 /// name needs to be unique so it does not collide with other names used by
21 /// an application, nor other applications.
22 ///
23 /// If the name is empty, then an implementation defined default name will
24 /// be used instead.
25 ///
26 /// # Examples
27 ///
28 /// ```
29 /// use opentelemetry::{global, metrics::MeterProvider};
30 /// use opentelemetry::KeyValue;
31 ///
32 /// let provider = global::meter_provider();
33 ///
34 /// // meter used in applications
35 /// let meter = provider.meter("my_app");
36 ///
37 /// // meter used in libraries/crates that optionally includes version and schema url
38 /// let meter = provider.versioned_meter(
39 /// "my_library",
40 /// Some(env!("CARGO_PKG_VERSION")),
41 /// Some("https://opentelemetry.io/schema/1.0.0"),
42 /// Some(vec![KeyValue::new("key", "value")]),
43 /// );
44 /// ```
45 fn meter(&self, name: impl Into<Cow<'static, str>>) -> Meter {
46 self.versioned_meter(
47 name,
48 None::<Cow<'static, str>>,
49 None::<Cow<'static, str>>,
50 None,
51 )
52 }
53
54 /// Returns a new versioned meter with a given name.
55 ///
56 /// The instrumentation name must be the name of the library providing instrumentation. This
57 /// name may be the same as the instrumented code only if that code provides built-in
58 /// instrumentation. If the instrumentation name is empty, then a implementation defined
59 /// default name will be used instead.
60 fn versioned_meter(
61 &self,
62 name: impl Into<Cow<'static, str>>,
63 version: Option<impl Into<Cow<'static, str>>>,
64 schema_url: Option<impl Into<Cow<'static, str>>>,
65 attributes: Option<Vec<KeyValue>>,
66 ) -> Meter;
67}
68
69/// Provides access to instrument instances for recording measurements.
70///
71/// ```
72/// use opentelemetry::{global, KeyValue};
73///
74/// let meter = global::meter("my-meter");
75///
76/// // Meters can create metric instruments that can record values of type u64 and f64
77///
78/// // u64 Counter
79/// let u64_counter = meter.u64_counter("my_u64_counter").init();
80///
81/// // Record measurements using the counter instrument add()
82/// u64_counter.add(
83/// 10,
84/// &[
85/// KeyValue::new("mykey1", "myvalue1"),
86/// KeyValue::new("mykey2", "myvalue2"),
87/// ]
88/// );
89///
90/// // f64 Counter
91/// let f64_counter = meter.f64_counter("my_f64_counter").init();
92///
93/// // Record measurements using the counter instrument add()
94/// f64_counter.add(
95/// 3.15,
96/// &[
97/// KeyValue::new("mykey1", "myvalue1"),
98/// KeyValue::new("mykey2", "myvalue2"),
99/// ],
100/// );
101///
102/// // u6 observable counter
103/// let observable_u4_counter = meter.u64_observable_counter("my_observable_u64_counter").init();
104///
105/// // Register a callback to this meter for an asynchronous instrument to record measurements
106/// meter.register_callback(&[observable_u4_counter.as_any()], move |observer| {
107/// observer.observe_u64(
108/// &observable_u4_counter,
109/// 1,
110/// &[
111/// KeyValue::new("mykey1", "myvalue1"),
112/// KeyValue::new("mykey2", "myvalue2"),
113/// ],
114/// )
115/// });
116///
117/// // f64 observable counter
118/// let observable_f64_counter = meter.f64_observable_counter("my_observable_f64_counter").init();
119///
120/// // Register a callback to this meter for an asynchronous instrument to record measurements
121/// meter.register_callback(&[observable_f64_counter.as_any()], move |observer| {
122/// observer.observe_f64(
123/// &observable_f64_counter,
124/// 1.55,
125/// &[
126/// KeyValue::new("mykey1", "myvalue1"),
127/// KeyValue::new("mykey2", "myvalue2"),
128/// ],
129/// )
130/// });
131///
132/// // i64 updown counter
133/// let updown_i64_counter = meter.i64_up_down_counter("my_updown_i64_counter").init();
134///
135/// // Record measurements using the updown counter instrument add()
136/// updown_i64_counter.add(
137/// -10,
138/// &
139/// [
140/// KeyValue::new("mykey1", "myvalue1"),
141/// KeyValue::new("mykey2", "myvalue2"),
142/// ],
143/// );
144///
145/// // f64 updown counter
146/// let updown_f64_counter = meter.f64_up_down_counter("my_updown_f64_counter").init();
147///
148/// // Record measurements using the updown counter instrument add()
149/// updown_f64_counter.add(
150/// -10.67,
151/// &
152/// [
153/// KeyValue::new("mykey1", "myvalue1"),
154/// KeyValue::new("mykey2", "myvalue2"),
155/// ],
156/// );
157///
158/// // i64 observable updown counter
159/// let observable_i64_up_down_counter = meter.i64_observable_up_down_counter("my_observable_i64_updown_counter").init();
160///
161/// // Register a callback to this meter for an asynchronous instrument to record measurements
162/// meter.register_callback(&[observable_i64_up_down_counter.as_any()], move |observer| {
163/// observer.observe_i64(
164/// &observable_i64_up_down_counter,
165/// 1,
166/// &[
167/// KeyValue::new("mykey1", "myvalue1"),
168/// KeyValue::new("mykey2", "myvalue2"),
169/// ],
170/// )
171/// });
172///
173/// // f64 observable updown counter
174/// let observable_f64_up_down_counter = meter.f64_observable_up_down_counter("my_observable_f64_updown_counter").init();
175///
176/// // Register a callback to this meter for an asynchronous instrument to record measurements
177/// meter.register_callback(&[observable_f64_up_down_counter.as_any()], move |observer| {
178/// observer.observe_f64(
179/// &observable_f64_up_down_counter,
180/// 1.16,
181/// &[
182/// KeyValue::new("mykey1", "myvalue1"),
183/// KeyValue::new("mykey2", "myvalue2"),
184/// ],
185/// )
186/// });
187///
188/// // Observable f64 gauge
189/// let f64_gauge = meter.f64_observable_gauge("my_f64_gauge").init();
190///
191/// // Register a callback to this meter for an asynchronous instrument to record measurements
192/// meter.register_callback(&[f64_gauge.as_any()], move |observer| {
193/// observer.observe_f64(
194/// &f64_gauge,
195/// 2.32,
196/// &[
197/// KeyValue::new("mykey1", "myvalue1"),
198/// KeyValue::new("mykey2", "myvalue2"),
199/// ],
200/// )
201/// });
202///
203/// // Observable i64 gauge
204/// let i64_gauge = meter.i64_observable_gauge("my_i64_gauge").init();
205///
206/// // Register a callback to this meter for an asynchronous instrument to record measurements
207/// meter.register_callback(&[i64_gauge.as_any()], move |observer| {
208/// observer.observe_i64(
209/// &i64_gauge,
210/// 12,
211/// &[
212/// KeyValue::new("mykey1", "myvalue1"),
213/// KeyValue::new("mykey2", "myvalue2"),
214/// ],
215/// )
216/// });
217///
218/// // Observable u64 gauge
219/// let u64_gauge = meter.u64_observable_gauge("my_u64_gauge").init();
220///
221/// // Register a callback to this meter for an asynchronous instrument to record measurements
222/// meter.register_callback(&[u64_gauge.as_any()], move |observer| {
223/// observer.observe_u64(
224/// &u64_gauge,
225/// 1,
226/// &[
227/// KeyValue::new("mykey1", "myvalue1"),
228/// KeyValue::new("mykey2", "myvalue2"),
229/// ],
230/// )
231/// });
232///
233/// // f64 histogram
234/// let f64_histogram = meter.f64_histogram("my_f64_histogram").init();
235///
236/// // Record measurements using the histogram instrument record()
237/// f64_histogram.record(
238/// 10.5,
239/// &[
240/// KeyValue::new("mykey1", "myvalue1"),
241/// KeyValue::new("mykey2", "myvalue2"),
242/// ],
243/// );
244///
245/// // u64 histogram
246/// let u64_histogram = meter.u64_histogram("my_u64_histogram").init();
247///
248/// // Record measurements using the histogram instrument record()
249/// u64_histogram.record(
250/// 12,
251/// &[
252/// KeyValue::new("mykey1", "myvalue1"),
253/// KeyValue::new("mykey2", "myvalue2"),
254/// ],
255/// );
256///
257/// ```
258#[derive(Clone)]
259pub struct Meter {
260 pub(crate) instrument_provider: Arc<dyn InstrumentProvider + Send + Sync>,
261}
262
263impl Meter {
264 /// Create a new named meter from an instrumentation provider
265 #[doc(hidden)]
266 pub fn new(instrument_provider: Arc<dyn InstrumentProvider + Send + Sync>) -> Self {
267 Meter {
268 instrument_provider,
269 }
270 }
271
272 /// creates an instrument builder for recording increasing values.
273 pub fn u64_counter(
274 &self,
275 name: impl Into<Cow<'static, str>>,
276 ) -> InstrumentBuilder<'_, Counter<u64>> {
277 InstrumentBuilder::new(self, name.into())
278 }
279
280 /// creates an instrument builder for recording increasing values.
281 pub fn f64_counter(
282 &self,
283 name: impl Into<Cow<'static, str>>,
284 ) -> InstrumentBuilder<'_, Counter<f64>> {
285 InstrumentBuilder::new(self, name.into())
286 }
287
288 /// creates an instrument builder for recording increasing values via callback.
289 pub fn u64_observable_counter(
290 &self,
291 name: impl Into<Cow<'static, str>>,
292 ) -> AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64> {
293 AsyncInstrumentBuilder::new(self, name.into())
294 }
295
296 /// creates an instrument builder for recording increasing values via callback.
297 pub fn f64_observable_counter(
298 &self,
299 name: impl Into<Cow<'static, str>>,
300 ) -> AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64> {
301 AsyncInstrumentBuilder::new(self, name.into())
302 }
303
304 /// creates an instrument builder for recording changes of a value.
305 pub fn i64_up_down_counter(
306 &self,
307 name: impl Into<Cow<'static, str>>,
308 ) -> InstrumentBuilder<'_, UpDownCounter<i64>> {
309 InstrumentBuilder::new(self, name.into())
310 }
311
312 /// creates an instrument builder for recording changes of a value.
313 pub fn f64_up_down_counter(
314 &self,
315 name: impl Into<Cow<'static, str>>,
316 ) -> InstrumentBuilder<'_, UpDownCounter<f64>> {
317 InstrumentBuilder::new(self, name.into())
318 }
319
320 /// creates an instrument builder for recording changes of a value via callback.
321 pub fn i64_observable_up_down_counter(
322 &self,
323 name: impl Into<Cow<'static, str>>,
324 ) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<i64>, i64> {
325 AsyncInstrumentBuilder::new(self, name.into())
326 }
327
328 /// creates an instrument builder for recording changes of a value via callback.
329 pub fn f64_observable_up_down_counter(
330 &self,
331 name: impl Into<Cow<'static, str>>,
332 ) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<f64>, f64> {
333 AsyncInstrumentBuilder::new(self, name.into())
334 }
335
336 /// creates an instrument builder for recording independent values.
337 pub fn u64_gauge(
338 &self,
339 name: impl Into<Cow<'static, str>>,
340 ) -> InstrumentBuilder<'_, Gauge<u64>> {
341 InstrumentBuilder::new(self, name.into())
342 }
343
344 /// creates an instrument builder for recording independent values.
345 pub fn f64_gauge(
346 &self,
347 name: impl Into<Cow<'static, str>>,
348 ) -> InstrumentBuilder<'_, Gauge<f64>> {
349 InstrumentBuilder::new(self, name.into())
350 }
351
352 /// creates an instrument builder for recording independent values.
353 pub fn i64_gauge(
354 &self,
355 name: impl Into<Cow<'static, str>>,
356 ) -> InstrumentBuilder<'_, Gauge<i64>> {
357 InstrumentBuilder::new(self, name.into())
358 }
359
360 /// creates an instrument builder for recording the current value via callback.
361 pub fn u64_observable_gauge(
362 &self,
363 name: impl Into<Cow<'static, str>>,
364 ) -> AsyncInstrumentBuilder<'_, ObservableGauge<u64>, u64> {
365 AsyncInstrumentBuilder::new(self, name.into())
366 }
367
368 /// creates an instrument builder for recording the current value via callback.
369 pub fn i64_observable_gauge(
370 &self,
371 name: impl Into<Cow<'static, str>>,
372 ) -> AsyncInstrumentBuilder<'_, ObservableGauge<i64>, i64> {
373 AsyncInstrumentBuilder::new(self, name.into())
374 }
375
376 /// creates an instrument builder for recording the current value via callback.
377 pub fn f64_observable_gauge(
378 &self,
379 name: impl Into<Cow<'static, str>>,
380 ) -> AsyncInstrumentBuilder<'_, ObservableGauge<f64>, f64> {
381 AsyncInstrumentBuilder::new(self, name.into())
382 }
383
384 /// creates an instrument builder for recording a distribution of values.
385 pub fn f64_histogram(
386 &self,
387 name: impl Into<Cow<'static, str>>,
388 ) -> InstrumentBuilder<'_, Histogram<f64>> {
389 InstrumentBuilder::new(self, name.into())
390 }
391
392 /// creates an instrument builder for recording a distribution of values.
393 pub fn u64_histogram(
394 &self,
395 name: impl Into<Cow<'static, str>>,
396 ) -> InstrumentBuilder<'_, Histogram<u64>> {
397 InstrumentBuilder::new(self, name.into())
398 }
399
400 /// Registers a callback to be called during the collection of a measurement
401 /// cycle.
402 ///
403 /// The instruments passed as arguments to be registered are the only
404 /// instruments that may observe values.
405 ///
406 /// If no instruments are passed, the callback will not be registered.
407 pub fn register_callback<F>(
408 &self,
409 instruments: &[Arc<dyn Any>],
410 callback: F,
411 ) -> Result<Box<dyn CallbackRegistration>>
412 where
413 F: Fn(&dyn Observer) + Send + Sync + 'static,
414 {
415 self.instrument_provider
416 .register_callback(instruments, Box::new(callback))
417 }
418}
419
420/// A token representing the unique registration of a callback for a set of
421/// instruments with a [Meter].
422pub trait CallbackRegistration: Send + Sync {
423 /// Removes the callback registration from its associated [Meter].
424 fn unregister(&mut self) -> Result<()>;
425}
426
427/// Records measurements for multiple instruments in a callback.
428pub trait Observer {
429 /// Records the f64 value with attributes for the observable.
430 fn observe_f64(&self, inst: &dyn AsyncInstrument<f64>, measurement: f64, attrs: &[KeyValue]);
431
432 /// Records the u64 value with attributes for the observable.
433 fn observe_u64(&self, inst: &dyn AsyncInstrument<u64>, measurement: u64, attrs: &[KeyValue]);
434
435 /// Records the i64 value with attributes for the observable.
436 fn observe_i64(&self, inst: &dyn AsyncInstrument<i64>, measurement: i64, attrs: &[KeyValue]);
437}
438
439impl fmt::Debug for Meter {
440 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
441 f.write_str("Meter")
442 }
443}