opentelemetry_api/metrics/
mod.rs

1//! # OpenTelemetry Metrics API
2
3use std::any::Any;
4use std::result;
5use std::sync::PoisonError;
6use std::{borrow::Cow, sync::Arc};
7use thiserror::Error;
8
9mod instruments;
10mod meter;
11pub mod noop;
12
13use crate::ExportError;
14pub use instruments::{
15    counter::{Counter, ObservableCounter, SyncCounter},
16    gauge::ObservableGauge,
17    histogram::{Histogram, SyncHistogram},
18    up_down_counter::{ObservableUpDownCounter, SyncUpDownCounter, UpDownCounter},
19    AsyncInstrument, AsyncInstrumentBuilder, Callback, InstrumentBuilder,
20};
21pub use meter::{CallbackRegistration, Meter, MeterProvider, Observer};
22
23/// A specialized `Result` type for metric operations.
24pub type Result<T> = result::Result<T, MetricsError>;
25
26/// Errors returned by the metrics API.
27#[derive(Error, Debug)]
28#[non_exhaustive]
29pub enum MetricsError {
30    /// Other errors not covered by specific cases.
31    #[error("Metrics error: {0}")]
32    Other(String),
33    /// Invalid configuration
34    #[error("Config error {0}")]
35    Config(String),
36    /// Fail to export metrics
37    #[error("Metrics exporter {} failed with {0}", .0.exporter_name())]
38    ExportErr(Box<dyn ExportError>),
39    /// Invalid instrument configuration such invalid instrument name, invalid instrument description, invalid instrument unit, etc.
40    /// See [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#general-characteristics)
41    /// for full list of requirements.
42    #[error("Invalid instrument configuration: {0}")]
43    InvalidInstrumentConfiguration(&'static str),
44}
45
46impl<T: ExportError> From<T> for MetricsError {
47    fn from(err: T) -> Self {
48        MetricsError::ExportErr(Box::new(err))
49    }
50}
51
52impl<T> From<PoisonError<T>> for MetricsError {
53    fn from(err: PoisonError<T>) -> Self {
54        MetricsError::Other(err.to_string())
55    }
56}
57
58/// Units denote underlying data units tracked by `Meter`s.
59#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
60pub struct Unit(Cow<'static, str>);
61
62impl Unit {
63    /// Create a new `Unit` from an `Into<String>`
64    pub fn new<S>(value: S) -> Self
65    where
66        S: Into<Cow<'static, str>>,
67    {
68        Unit(value.into())
69    }
70
71    /// View unit as &str
72    pub fn as_str(&self) -> &str {
73        self.0.as_ref()
74    }
75}
76
77impl AsRef<str> for Unit {
78    #[inline]
79    fn as_ref(&self) -> &str {
80        self.0.as_ref()
81    }
82}
83
84/// SDK implemented trait for creating instruments
85pub trait InstrumentProvider {
86    /// creates an instrument for recording increasing values.
87    fn u64_counter(
88        &self,
89        _name: Cow<'static, str>,
90        _description: Option<Cow<'static, str>>,
91        _unit: Option<Unit>,
92    ) -> Result<Counter<u64>> {
93        Ok(Counter::new(Arc::new(noop::NoopSyncInstrument::new())))
94    }
95
96    /// creates an instrument for recording increasing values.
97    fn f64_counter(
98        &self,
99        _name: Cow<'static, str>,
100        _description: Option<Cow<'static, str>>,
101        _unit: Option<Unit>,
102    ) -> Result<Counter<f64>> {
103        Ok(Counter::new(Arc::new(noop::NoopSyncInstrument::new())))
104    }
105
106    /// creates an instrument for recording increasing values via callback.
107    fn u64_observable_counter(
108        &self,
109        _name: Cow<'static, str>,
110        _description: Option<Cow<'static, str>>,
111        _unit: Option<Unit>,
112        _callback: Vec<Callback<u64>>,
113    ) -> Result<ObservableCounter<u64>> {
114        Ok(ObservableCounter::new(Arc::new(
115            noop::NoopAsyncInstrument::new(),
116        )))
117    }
118
119    /// creates an instrument for recording increasing values via callback.
120    fn f64_observable_counter(
121        &self,
122        _name: Cow<'static, str>,
123        _description: Option<Cow<'static, str>>,
124        _unit: Option<Unit>,
125        _callback: Vec<Callback<f64>>,
126    ) -> Result<ObservableCounter<f64>> {
127        Ok(ObservableCounter::new(Arc::new(
128            noop::NoopAsyncInstrument::new(),
129        )))
130    }
131
132    /// creates an instrument for recording changes of a value.
133    fn i64_up_down_counter(
134        &self,
135        _name: Cow<'static, str>,
136        _description: Option<Cow<'static, str>>,
137        _unit: Option<Unit>,
138    ) -> Result<UpDownCounter<i64>> {
139        Ok(UpDownCounter::new(
140            Arc::new(noop::NoopSyncInstrument::new()),
141        ))
142    }
143
144    /// creates an instrument for recording changes of a value.
145    fn f64_up_down_counter(
146        &self,
147        _name: Cow<'static, str>,
148        _description: Option<Cow<'static, str>>,
149        _unit: Option<Unit>,
150    ) -> Result<UpDownCounter<f64>> {
151        Ok(UpDownCounter::new(
152            Arc::new(noop::NoopSyncInstrument::new()),
153        ))
154    }
155
156    /// creates an instrument for recording changes of a value.
157    fn i64_observable_up_down_counter(
158        &self,
159        _name: Cow<'static, str>,
160        _description: Option<Cow<'static, str>>,
161        _unit: Option<Unit>,
162        _callback: Vec<Callback<i64>>,
163    ) -> Result<ObservableUpDownCounter<i64>> {
164        Ok(ObservableUpDownCounter::new(Arc::new(
165            noop::NoopAsyncInstrument::new(),
166        )))
167    }
168
169    /// creates an instrument for recording changes of a value via callback.
170    fn f64_observable_up_down_counter(
171        &self,
172        _name: Cow<'static, str>,
173        _description: Option<Cow<'static, str>>,
174        _unit: Option<Unit>,
175        _callback: Vec<Callback<f64>>,
176    ) -> Result<ObservableUpDownCounter<f64>> {
177        Ok(ObservableUpDownCounter::new(Arc::new(
178            noop::NoopAsyncInstrument::new(),
179        )))
180    }
181
182    /// creates an instrument for recording the current value via callback.
183    fn u64_observable_gauge(
184        &self,
185        _name: Cow<'static, str>,
186        _description: Option<Cow<'static, str>>,
187        _unit: Option<Unit>,
188        _callback: Vec<Callback<u64>>,
189    ) -> Result<ObservableGauge<u64>> {
190        Ok(ObservableGauge::new(Arc::new(
191            noop::NoopAsyncInstrument::new(),
192        )))
193    }
194
195    /// creates an instrument for recording the current value via callback.
196    fn i64_observable_gauge(
197        &self,
198        _name: Cow<'static, str>,
199        _description: Option<Cow<'static, str>>,
200        _unit: Option<Unit>,
201        _callback: Vec<Callback<i64>>,
202    ) -> Result<ObservableGauge<i64>> {
203        Ok(ObservableGauge::new(Arc::new(
204            noop::NoopAsyncInstrument::new(),
205        )))
206    }
207
208    /// creates an instrument for recording the current value via callback.
209    fn f64_observable_gauge(
210        &self,
211        _name: Cow<'static, str>,
212        _description: Option<Cow<'static, str>>,
213        _unit: Option<Unit>,
214        _callback: Vec<Callback<f64>>,
215    ) -> Result<ObservableGauge<f64>> {
216        Ok(ObservableGauge::new(Arc::new(
217            noop::NoopAsyncInstrument::new(),
218        )))
219    }
220
221    /// creates an instrument for recording a distribution of values.
222    fn f64_histogram(
223        &self,
224        _name: Cow<'static, str>,
225        _description: Option<Cow<'static, str>>,
226        _unit: Option<Unit>,
227    ) -> Result<Histogram<f64>> {
228        Ok(Histogram::new(Arc::new(noop::NoopSyncInstrument::new())))
229    }
230
231    /// creates an instrument for recording a distribution of values.
232    fn u64_histogram(
233        &self,
234        _name: Cow<'static, str>,
235        _description: Option<Cow<'static, str>>,
236        _unit: Option<Unit>,
237    ) -> Result<Histogram<u64>> {
238        Ok(Histogram::new(Arc::new(noop::NoopSyncInstrument::new())))
239    }
240
241    /// creates an instrument for recording a distribution of values.
242    fn i64_histogram(
243        &self,
244        _name: Cow<'static, str>,
245        _description: Option<Cow<'static, str>>,
246        _unit: Option<Unit>,
247    ) -> Result<Histogram<i64>> {
248        Ok(Histogram::new(Arc::new(noop::NoopSyncInstrument::new())))
249    }
250
251    /// Captures the function that will be called during data collection.
252    ///
253    /// It is only valid to call `observe` within the scope of the passed function.
254    fn register_callback(
255        &self,
256        instruments: &[Arc<dyn Any>],
257        callbacks: Box<MultiInstrumentCallback>,
258    ) -> Result<Box<dyn CallbackRegistration>>;
259}
260
261type MultiInstrumentCallback = dyn Fn(&dyn Observer) + Send + Sync;