opentelemetry/metrics/instruments/
mod.rs1use gauge::{Gauge, ObservableGauge};
2
3use crate::metrics::Meter;
4use crate::KeyValue;
5use core::fmt;
6use std::borrow::Cow;
7use std::marker;
8
9use super::{
10 Counter, Histogram, InstrumentProvider, ObservableCounter, ObservableUpDownCounter,
11 UpDownCounter,
12};
13
14pub(super) mod counter;
15pub(super) mod gauge;
16pub(super) mod histogram;
17pub(super) mod up_down_counter;
18
19pub trait AsyncInstrument<T>: Send + Sync {
21 fn observe(&self, measurement: T, attributes: &[KeyValue]);
25}
26
27pub trait SyncInstrument<T>: Send + Sync {
29 fn measure(&self, measurement: T, attributes: &[KeyValue]);
31}
32
33#[non_exhaustive] pub struct HistogramBuilder<'a, T> {
36 pub instrument_provider: &'a dyn InstrumentProvider,
38
39 pub name: Cow<'static, str>,
41
42 pub description: Option<Cow<'static, str>>,
44
45 pub unit: Option<Cow<'static, str>>,
47
48 pub boundaries: Option<Vec<f64>>,
50
51 _marker: marker::PhantomData<T>,
53}
54
55impl<'a, T> HistogramBuilder<'a, T> {
56 pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
58 HistogramBuilder {
59 instrument_provider: meter.instrument_provider.as_ref(),
60 name,
61 description: None,
62 unit: None,
63 boundaries: None,
64 _marker: marker::PhantomData,
65 }
66 }
67
68 pub fn with_description<S: Into<Cow<'static, str>>>(mut self, description: S) -> Self {
70 self.description = Some(description.into());
71 self
72 }
73
74 pub fn with_unit<S: Into<Cow<'static, str>>>(mut self, unit: S) -> Self {
82 self.unit = Some(unit.into());
83 self
84 }
85
86 pub fn with_boundaries(mut self, boundaries: Vec<f64>) -> Self {
111 self.boundaries = Some(boundaries);
112 self
113 }
114}
115
116impl HistogramBuilder<'_, Histogram<f64>> {
117 pub fn build(self) -> Histogram<f64> {
123 self.instrument_provider.f64_histogram(self)
124 }
125}
126
127impl HistogramBuilder<'_, Histogram<u64>> {
128 pub fn build(self) -> Histogram<u64> {
134 self.instrument_provider.u64_histogram(self)
135 }
136}
137
138#[non_exhaustive] pub struct InstrumentBuilder<'a, T> {
141 pub instrument_provider: &'a dyn InstrumentProvider,
143
144 pub name: Cow<'static, str>,
146
147 pub description: Option<Cow<'static, str>>,
149
150 pub unit: Option<Cow<'static, str>>,
152
153 _marker: marker::PhantomData<T>,
154}
155
156impl<'a, T> InstrumentBuilder<'a, T> {
157 pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
159 InstrumentBuilder {
160 instrument_provider: meter.instrument_provider.as_ref(),
161 name,
162 description: None,
163 unit: None,
164 _marker: marker::PhantomData,
165 }
166 }
167
168 pub fn with_description<S: Into<Cow<'static, str>>>(mut self, description: S) -> Self {
170 self.description = Some(description.into());
171 self
172 }
173
174 pub fn with_unit<S: Into<Cow<'static, str>>>(mut self, unit: S) -> Self {
182 self.unit = Some(unit.into());
183 self
184 }
185}
186
187macro_rules! build_instrument {
188 ($name:ident, $inst:ty) => {
189 impl<'a> InstrumentBuilder<'a, $inst> {
190 #[doc = concat!("Validates the instrument configuration and creates a new `", stringify!($inst), "`.")]
191 pub fn build(self) -> $inst {
194 self.instrument_provider.$name(self)
195 }
196 }
197 };
198}
199
200build_instrument!(u64_counter, Counter<u64>);
201build_instrument!(f64_counter, Counter<f64>);
202build_instrument!(u64_gauge, Gauge<u64>);
203build_instrument!(f64_gauge, Gauge<f64>);
204build_instrument!(i64_gauge, Gauge<i64>);
205build_instrument!(i64_up_down_counter, UpDownCounter<i64>);
206build_instrument!(f64_up_down_counter, UpDownCounter<f64>);
207
208impl<T> fmt::Debug for InstrumentBuilder<'_, T> {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 f.debug_struct("InstrumentBuilder")
211 .field("name", &self.name)
212 .field("description", &self.description)
213 .field("unit", &self.unit)
214 .field("kind", &std::any::type_name::<T>())
215 .finish()
216 }
217}
218
219impl<T> fmt::Debug for HistogramBuilder<'_, T> {
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 f.debug_struct("HistogramBuilder")
222 .field("name", &self.name)
223 .field("description", &self.description)
224 .field("unit", &self.unit)
225 .field("boundaries", &self.boundaries)
226 .field(
227 "kind",
228 &format!("Histogram<{}>", &std::any::type_name::<T>()),
229 )
230 .finish()
231 }
232}
233
234pub type Callback<T> = Box<dyn Fn(&dyn AsyncInstrument<T>) + Send + Sync>;
242
243#[non_exhaustive] pub struct AsyncInstrumentBuilder<'a, I, M> {
246 pub instrument_provider: &'a dyn InstrumentProvider,
248
249 pub name: Cow<'static, str>,
251
252 pub description: Option<Cow<'static, str>>,
254
255 pub unit: Option<Cow<'static, str>>,
257
258 pub callbacks: Vec<Callback<M>>,
260
261 _inst: marker::PhantomData<I>,
262}
263
264impl<'a, I, M> AsyncInstrumentBuilder<'a, I, M> {
265 pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
267 AsyncInstrumentBuilder {
268 instrument_provider: meter.instrument_provider.as_ref(),
269 name,
270 description: None,
271 unit: None,
272 _inst: marker::PhantomData,
273 callbacks: Vec::new(),
274 }
275 }
276
277 pub fn with_description<S: Into<Cow<'static, str>>>(mut self, description: S) -> Self {
279 self.description = Some(description.into());
280 self
281 }
282
283 pub fn with_unit<S: Into<Cow<'static, str>>>(mut self, unit: S) -> Self {
291 self.unit = Some(unit.into());
292 self
293 }
294
295 pub fn with_callback<F>(mut self, callback: F) -> Self
297 where
298 F: Fn(&dyn AsyncInstrument<M>) + Send + Sync + 'static,
299 {
300 self.callbacks.push(Box::new(callback));
301 self
302 }
303}
304
305macro_rules! build_async_instrument {
306 ($name:ident, $inst:ty, $measurement:ty) => {
307 impl<'a> AsyncInstrumentBuilder<'a, $inst, $measurement> {
308 #[doc = concat!("Validates the instrument configuration and creates a new `", stringify!($inst), "`.")]
309 pub fn build(self) -> $inst {
312 self.instrument_provider.$name(self)
313 }
314 }
315 };
316}
317
318build_async_instrument!(u64_observable_counter, ObservableCounter<u64>, u64);
319build_async_instrument!(f64_observable_counter, ObservableCounter<f64>, f64);
320build_async_instrument!(u64_observable_gauge, ObservableGauge<u64>, u64);
321build_async_instrument!(f64_observable_gauge, ObservableGauge<f64>, f64);
322build_async_instrument!(i64_observable_gauge, ObservableGauge<i64>, i64);
323build_async_instrument!(
324 i64_observable_up_down_counter,
325 ObservableUpDownCounter<i64>,
326 i64
327);
328build_async_instrument!(
329 f64_observable_up_down_counter,
330 ObservableUpDownCounter<f64>,
331 f64
332);
333
334impl<I, M> fmt::Debug for AsyncInstrumentBuilder<'_, I, M>
335where
336 I: AsyncInstrument<M>,
337{
338 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339 f.debug_struct("InstrumentBuilder")
340 .field("name", &self.name)
341 .field("description", &self.description)
342 .field("unit", &self.unit)
343 .field("kind", &std::any::type_name::<I>())
344 .field("callbacks_len", &self.callbacks.len())
345 .finish()
346 }
347}