opentelemetry_spanprocessor_any/metrics/
counter.rs

1use crate::{
2    metrics::{
3        sync_instrument::{SyncBoundInstrument, SyncInstrument},
4        Descriptor, InstrumentKind, Measurement, Meter, Number, NumberKind, Result, Unit,
5    },
6    KeyValue,
7};
8use std::marker;
9
10/// A metric that accumulates values.
11#[derive(Clone, Debug)]
12pub struct Counter<T>(SyncInstrument<T>);
13
14impl<T> Counter<T>
15where
16    T: Into<Number>,
17{
18    /// Creates a bound instrument for this counter. The attributes are associated with
19    /// values recorded via subsequent calls to record.
20    pub fn bind(&self, attributes: &[KeyValue]) -> BoundCounter<T> {
21        let bound_instrument = self.0.bind(attributes);
22
23        BoundCounter { bound_instrument }
24    }
25
26    /// Increment this counter by a given T
27    pub fn add(&self, value: T, attributes: &[KeyValue]) {
28        self.0.direct_record(value.into(), attributes)
29    }
30
31    /// Creates a Measurement for use with batch recording.
32    pub fn measurement(&self, value: T) -> Measurement {
33        Measurement::new(value.into(), self.0.instrument().clone())
34    }
35}
36
37/// BoundCounter is a bound instrument for counters.
38#[derive(Clone, Debug)]
39pub struct BoundCounter<T> {
40    bound_instrument: SyncBoundInstrument<T>,
41}
42
43impl<T> BoundCounter<T>
44where
45    T: Into<Number>,
46{
47    /// Increment this counter by a given T
48    pub fn add(&self, value: T) {
49        self.bound_instrument.direct_record(value.into())
50    }
51}
52
53/// Configuration for building a counter.
54#[derive(Debug)]
55pub struct CounterBuilder<'a, T> {
56    meter: &'a Meter,
57    descriptor: Descriptor,
58    _marker: marker::PhantomData<T>,
59}
60
61impl<'a, T> CounterBuilder<'a, T> {
62    /// Create a new counter builder
63    pub(crate) fn new(meter: &'a Meter, name: String, number_kind: NumberKind) -> Self {
64        CounterBuilder {
65            meter,
66            descriptor: Descriptor::new(
67                name,
68                meter.instrumentation_library().name,
69                meter.instrumentation_library().version,
70                InstrumentKind::Counter,
71                number_kind,
72            ),
73            _marker: marker::PhantomData,
74        }
75    }
76
77    /// Set the description for this counter
78    pub fn with_description<S: Into<String>>(mut self, description: S) -> Self {
79        self.descriptor.set_description(description.into());
80        self
81    }
82
83    /// Set the unit for this counter.
84    pub fn with_unit(mut self, unit: Unit) -> Self {
85        self.descriptor.config.unit = Some(unit);
86        self
87    }
88
89    /// Creates a new counter instrument.
90    pub fn try_init(self) -> Result<Counter<T>> {
91        let instrument = self.meter.new_sync_instrument(self.descriptor)?;
92        Ok(Counter(SyncInstrument::new(instrument)))
93    }
94
95    /// Creates a new counter instrument.
96    ///
97    /// # Panics
98    ///
99    /// This function panics if the instrument cannot be created. Use try_init if you want to
100    /// handle errors.
101    pub fn init(self) -> Counter<T> {
102        Counter(SyncInstrument::new(
103            self.meter.new_sync_instrument(self.descriptor).unwrap(),
104        ))
105    }
106}