aws_smithy_observability/
instruments.rs1use std::{borrow::Cow, fmt::Debug, marker::PhantomData, sync::Arc};
9
10use crate::{meter::Meter, Attributes, Context};
11
12#[non_exhaustive]
14pub struct InstrumentBuilder<'a, T> {
15 instrument_provider: &'a dyn ProvideInstrument,
16 name: Cow<'static, str>,
17 description: Option<Cow<'static, str>>,
18 units: Option<Cow<'static, str>>,
19 _phantom: PhantomData<T>,
20}
21
22impl<'a, T> InstrumentBuilder<'a, T> {
23 pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
25 InstrumentBuilder {
26 instrument_provider: meter.instrument_provider.as_ref(),
27 name,
28 description: None,
29 units: None,
30 _phantom: PhantomData::<T>,
31 }
32 }
33
34 pub fn get_name(&self) -> &Cow<'static, str> {
36 &self.name
37 }
38
39 pub fn set_description(mut self, description: impl Into<Cow<'static, str>>) -> Self {
41 self.description = Some(description.into());
42 self
43 }
44
45 pub fn get_description(&self) -> &Option<Cow<'static, str>> {
47 &self.description
48 }
49
50 pub fn set_units(mut self, units: impl Into<Cow<'static, str>>) -> Self {
52 self.units = Some(units.into());
53 self
54 }
55
56 pub fn get_units(&self) -> &Option<Cow<'static, str>> {
58 &self.units
59 }
60}
61
62macro_rules! build_instrument {
65 ($name:ident, $instrument:ty) => {
66 impl<'a> InstrumentBuilder<'a, $instrument> {
67 #[doc = concat!("Create a new `", stringify!($instrument), "`.")]
68 pub fn build(self) -> $instrument {
69 self.instrument_provider.$name(self)
70 }
71 }
72 };
73}
74
75build_instrument!(create_histogram, Arc<dyn Histogram>);
76build_instrument!(create_monotonic_counter, Arc<dyn MonotonicCounter>);
77build_instrument!(create_up_down_counter, Arc<dyn UpDownCounter>);
78
79#[non_exhaustive]
81pub struct AsyncInstrumentBuilder<'a, T, M> {
82 instrument_provider: &'a dyn ProvideInstrument,
83 name: Cow<'static, str>,
84 #[allow(clippy::type_complexity)]
88 pub callback: Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync>,
89 description: Option<Cow<'static, str>>,
90 units: Option<Cow<'static, str>>,
91 _phantom: PhantomData<T>,
92}
93
94#[allow(clippy::type_complexity)]
95impl<'a, T, M> AsyncInstrumentBuilder<'a, T, M> {
96 pub(crate) fn new(
98 meter: &'a Meter,
99 name: Cow<'static, str>,
100 callback: Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync>,
101 ) -> Self {
102 AsyncInstrumentBuilder {
103 instrument_provider: meter.instrument_provider.as_ref(),
104 name,
105 callback,
106 description: None,
107 units: None,
108 _phantom: PhantomData::<T>,
109 }
110 }
111
112 pub fn get_name(&self) -> &Cow<'static, str> {
114 &self.name
115 }
116
117 pub fn get_callback(&self) -> Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync> {
119 self.callback.clone()
120 }
121
122 pub fn set_description(mut self, description: impl Into<Cow<'static, str>>) -> Self {
124 self.description = Some(description.into());
125 self
126 }
127
128 pub fn get_description(&self) -> &Option<Cow<'static, str>> {
130 &self.description
131 }
132
133 pub fn set_units(mut self, units: impl Into<Cow<'static, str>>) -> Self {
135 self.units = Some(units.into());
136 self
137 }
138
139 pub fn get_units(&self) -> &Option<Cow<'static, str>> {
141 &self.units
142 }
143}
144
145macro_rules! build_async_instrument {
149 ($name:ident, $instrument:ty, $measurement:ty) => {
150 impl<'a> AsyncInstrumentBuilder<'a, $instrument, $measurement> {
151 #[doc = concat!("Create a new `", stringify!($instrument), "`.")]
152 pub fn build(self) -> $instrument {
153 self.instrument_provider.$name(self)
154 }
155 }
156 };
157}
158
159build_async_instrument!(create_gauge, Arc<dyn AsyncMeasure<Value = f64>>, f64);
160build_async_instrument!(
161 create_async_up_down_counter,
162 Arc<dyn AsyncMeasure<Value = i64>>,
163 i64
164);
165build_async_instrument!(
166 create_async_monotonic_counter,
167 Arc<dyn AsyncMeasure<Value = u64>>,
168 u64
169);
170
171pub trait ProvideInstrument: Send + Sync + Debug {
173 #[allow(clippy::type_complexity)]
175 fn create_gauge(
176 &self,
177 builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = f64>>, f64>,
178 ) -> Arc<dyn AsyncMeasure<Value = f64>>;
179
180 fn create_up_down_counter(
182 &self,
183 builder: InstrumentBuilder<'_, Arc<dyn UpDownCounter>>,
184 ) -> Arc<dyn UpDownCounter>;
185
186 #[allow(clippy::type_complexity)]
188 fn create_async_up_down_counter(
189 &self,
190 builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = i64>>, i64>,
191 ) -> Arc<dyn AsyncMeasure<Value = i64>>;
192
193 fn create_monotonic_counter(
195 &self,
196 builder: InstrumentBuilder<'_, Arc<dyn MonotonicCounter>>,
197 ) -> Arc<dyn MonotonicCounter>;
198
199 #[allow(clippy::type_complexity)]
201 fn create_async_monotonic_counter(
202 &self,
203 builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = u64>>, u64>,
204 ) -> Arc<dyn AsyncMeasure<Value = u64>>;
205
206 fn create_histogram(
208 &self,
209 builder: InstrumentBuilder<'_, Arc<dyn Histogram>>,
210 ) -> Arc<dyn Histogram>;
211}
212
213pub trait Histogram: Send + Sync + Debug {
215 fn record(&self, value: f64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
217}
218
219pub trait MonotonicCounter: Send + Sync + Debug {
221 fn add(&self, value: u64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
223}
224
225pub trait UpDownCounter: Send + Sync + Debug {
227 fn add(&self, value: i64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
229}
230
231pub trait AsyncMeasure: Send + Sync + Debug {
233 type Value;
235
236 fn record(
238 &self,
239 value: Self::Value,
240 attributes: Option<&Attributes>,
241 context: Option<&dyn Context>,
242 );
243
244 fn stop(&self);
246}