opentelemetry/metrics/instruments/
up_down_counter.rs

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