aws_smithy_observability/
instruments.rs
use std::{borrow::Cow, fmt::Debug, marker::PhantomData, sync::Arc};
use crate::{meter::Meter, Attributes, Context};
#[non_exhaustive]
pub struct InstrumentBuilder<'a, T> {
instrument_provider: &'a dyn ProvideInstrument,
name: Cow<'static, str>,
description: Option<Cow<'static, str>>,
units: Option<Cow<'static, str>>,
_phantom: PhantomData<T>,
}
impl<'a, T> InstrumentBuilder<'a, T> {
pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
InstrumentBuilder {
instrument_provider: meter.instrument_provider.as_ref(),
name,
description: None,
units: None,
_phantom: PhantomData::<T>,
}
}
pub fn get_name(&self) -> &Cow<'static, str> {
&self.name
}
pub fn set_description(mut self, description: impl Into<Cow<'static, str>>) -> Self {
self.description = Some(description.into());
self
}
pub fn get_description(&self) -> &Option<Cow<'static, str>> {
&self.description
}
pub fn set_units(mut self, units: impl Into<Cow<'static, str>>) -> Self {
self.units = Some(units.into());
self
}
pub fn get_units(&self) -> &Option<Cow<'static, str>> {
&self.units
}
}
macro_rules! build_instrument {
($name:ident, $instrument:ty) => {
impl<'a> InstrumentBuilder<'a, $instrument> {
#[doc = concat!("Create a new `", stringify!($instrument), "`.")]
pub fn build(self) -> $instrument {
self.instrument_provider.$name(self)
}
}
};
}
build_instrument!(create_histogram, Arc<dyn Histogram>);
build_instrument!(create_monotonic_counter, Arc<dyn MonotonicCounter>);
build_instrument!(create_up_down_counter, Arc<dyn UpDownCounter>);
#[non_exhaustive]
pub struct AsyncInstrumentBuilder<'a, T, M> {
instrument_provider: &'a dyn ProvideInstrument,
name: Cow<'static, str>,
#[allow(clippy::type_complexity)]
pub callback: Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync>,
description: Option<Cow<'static, str>>,
units: Option<Cow<'static, str>>,
_phantom: PhantomData<T>,
}
#[allow(clippy::type_complexity)]
impl<'a, T, M> AsyncInstrumentBuilder<'a, T, M> {
pub(crate) fn new(
meter: &'a Meter,
name: Cow<'static, str>,
callback: Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync>,
) -> Self {
AsyncInstrumentBuilder {
instrument_provider: meter.instrument_provider.as_ref(),
name,
callback,
description: None,
units: None,
_phantom: PhantomData::<T>,
}
}
pub fn get_name(&self) -> &Cow<'static, str> {
&self.name
}
pub fn get_callback(&self) -> Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync> {
self.callback.clone()
}
pub fn set_description(mut self, description: impl Into<Cow<'static, str>>) -> Self {
self.description = Some(description.into());
self
}
pub fn get_description(&self) -> &Option<Cow<'static, str>> {
&self.description
}
pub fn set_units(mut self, units: impl Into<Cow<'static, str>>) -> Self {
self.units = Some(units.into());
self
}
pub fn get_units(&self) -> &Option<Cow<'static, str>> {
&self.units
}
}
macro_rules! build_async_instrument {
($name:ident, $instrument:ty, $measurement:ty) => {
impl<'a> AsyncInstrumentBuilder<'a, $instrument, $measurement> {
#[doc = concat!("Create a new `", stringify!($instrument), "`.")]
pub fn build(self) -> $instrument {
self.instrument_provider.$name(self)
}
}
};
}
build_async_instrument!(create_gauge, Arc<dyn AsyncMeasure<Value = f64>>, f64);
build_async_instrument!(
create_async_up_down_counter,
Arc<dyn AsyncMeasure<Value = i64>>,
i64
);
build_async_instrument!(
create_async_monotonic_counter,
Arc<dyn AsyncMeasure<Value = u64>>,
u64
);
pub trait ProvideInstrument: Send + Sync + Debug {
#[allow(clippy::type_complexity)]
fn create_gauge(
&self,
builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = f64>>, f64>,
) -> Arc<dyn AsyncMeasure<Value = f64>>;
fn create_up_down_counter(
&self,
builder: InstrumentBuilder<'_, Arc<dyn UpDownCounter>>,
) -> Arc<dyn UpDownCounter>;
#[allow(clippy::type_complexity)]
fn create_async_up_down_counter(
&self,
builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = i64>>, i64>,
) -> Arc<dyn AsyncMeasure<Value = i64>>;
fn create_monotonic_counter(
&self,
builder: InstrumentBuilder<'_, Arc<dyn MonotonicCounter>>,
) -> Arc<dyn MonotonicCounter>;
#[allow(clippy::type_complexity)]
fn create_async_monotonic_counter(
&self,
builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = u64>>, u64>,
) -> Arc<dyn AsyncMeasure<Value = u64>>;
fn create_histogram(
&self,
builder: InstrumentBuilder<'_, Arc<dyn Histogram>>,
) -> Arc<dyn Histogram>;
}
pub trait Histogram: Send + Sync + Debug {
fn record(&self, value: f64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
}
pub trait MonotonicCounter: Send + Sync + Debug {
fn add(&self, value: u64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
}
pub trait UpDownCounter: Send + Sync + Debug {
fn add(&self, value: i64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
}
pub trait AsyncMeasure: Send + Sync + Debug {
type Value;
fn record(
&self,
value: Self::Value,
attributes: Option<&Attributes>,
context: Option<&dyn Context>,
);
fn stop(&self);
}