opentelemetry/metrics/instruments/
counter.rs

1use crate::{
2    metrics::{AsyncInstrument, AsyncInstrumentBuilder, InstrumentBuilder, MetricsError},
3    KeyValue,
4};
5use core::fmt;
6use std::any::Any;
7use std::sync::Arc;
8
9/// An SDK implemented instrument that records increasing values.
10pub trait SyncCounter<T> {
11    /// Records an increment to the counter.
12    fn add(&self, value: T, attributes: &[KeyValue]);
13}
14
15/// An instrument that records increasing values.
16#[derive(Clone)]
17pub struct Counter<T>(Arc<dyn SyncCounter<T> + Send + Sync>);
18
19impl<T> fmt::Debug for Counter<T>
20where
21    T: fmt::Debug,
22{
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        f.write_fmt(format_args!("Counter<{}>", std::any::type_name::<T>()))
25    }
26}
27
28impl<T> Counter<T> {
29    /// Create a new counter.
30    pub fn new(inner: Arc<dyn SyncCounter<T> + Send + Sync>) -> Self {
31        Counter(inner)
32    }
33
34    /// Records an increment to the counter.
35    pub fn add(&self, value: T, attributes: &[KeyValue]) {
36        self.0.add(value, attributes)
37    }
38}
39
40impl TryFrom<InstrumentBuilder<'_, Counter<u64>>> for Counter<u64> {
41    type Error = MetricsError;
42
43    fn try_from(builder: InstrumentBuilder<'_, Counter<u64>>) -> Result<Self, Self::Error> {
44        builder
45            .instrument_provider
46            .u64_counter(builder.name, builder.description, builder.unit)
47    }
48}
49
50impl TryFrom<InstrumentBuilder<'_, Counter<f64>>> for Counter<f64> {
51    type Error = MetricsError;
52
53    fn try_from(builder: InstrumentBuilder<'_, Counter<f64>>) -> Result<Self, Self::Error> {
54        builder
55            .instrument_provider
56            .f64_counter(builder.name, builder.description, builder.unit)
57    }
58}
59
60/// An async instrument that records increasing values.
61#[derive(Clone)]
62pub struct ObservableCounter<T>(Arc<dyn AsyncInstrument<T>>);
63
64impl<T> ObservableCounter<T> {
65    /// Create a new observable counter.
66    pub fn new(inner: Arc<dyn AsyncInstrument<T>>) -> Self {
67        ObservableCounter(inner)
68    }
69}
70
71impl<T> fmt::Debug for ObservableCounter<T> {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        f.write_fmt(format_args!(
74            "ObservableCounter<{}>",
75            std::any::type_name::<T>()
76        ))
77    }
78}
79
80impl<T> ObservableCounter<T> {
81    /// Records an increment to the counter.
82    ///
83    /// It is only valid to call this within a callback. If called outside of the
84    /// registered callback it should have no effect on the instrument, and an
85    /// error will be reported via the error handler.
86    pub fn observe(&self, value: T, attributes: &[KeyValue]) {
87        self.0.observe(value, attributes)
88    }
89
90    /// Used for SDKs to downcast instruments in callbacks.
91    pub fn as_any(&self) -> Arc<dyn Any> {
92        self.0.as_any()
93    }
94}
95
96impl<T> AsyncInstrument<T> for ObservableCounter<T> {
97    fn observe(&self, measurement: T, attributes: &[KeyValue]) {
98        self.0.observe(measurement, attributes)
99    }
100
101    fn as_any(&self) -> Arc<dyn Any> {
102        self.0.as_any()
103    }
104}
105
106impl TryFrom<AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64>> for ObservableCounter<u64> {
107    type Error = MetricsError;
108
109    fn try_from(
110        builder: AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64>,
111    ) -> Result<Self, Self::Error> {
112        builder.meter.instrument_provider.u64_observable_counter(
113            builder.name,
114            builder.description,
115            builder.unit,
116            builder.callbacks,
117        )
118    }
119}
120
121impl TryFrom<AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64>> for ObservableCounter<f64> {
122    type Error = MetricsError;
123
124    fn try_from(
125        builder: AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64>,
126    ) -> Result<Self, Self::Error> {
127        builder.meter.instrument_provider.f64_observable_counter(
128            builder.name,
129            builder.description,
130            builder.unit,
131            builder.callbacks,
132        )
133    }
134}