use std::sync::Arc; use metrics::{atomics::AtomicU64, HistogramFn}; use metrics_util::{registry::GenerationalStorage, AtomicBucket}; use quanta::Instant; pub type GenerationalAtomicStorage = GenerationalStorage; /// Atomic metric storage for the prometheus exporter. #[derive(Debug)] pub struct AtomicStorage; impl metrics_util::registry::Storage for AtomicStorage { type Counter = Arc; type Gauge = Arc; type Histogram = Arc>; fn counter(&self, _: &K) -> Self::Counter { Arc::new(AtomicU64::new(0)) } fn gauge(&self, _: &K) -> Self::Gauge { Arc::new(AtomicU64::new(0)) } fn histogram(&self, _: &K) -> Self::Histogram { Arc::new(AtomicBucketInstant::new()) } } /// An `AtomicBucket` newtype wrapper that tracks the time of value insertion. #[derive(Debug)] pub struct AtomicBucketInstant { inner: AtomicBucket<(T, Instant)>, } impl AtomicBucketInstant { fn new() -> AtomicBucketInstant { Self { inner: AtomicBucket::new() } } pub fn clear_with(&self, f: F) where F: FnMut(&[(T, Instant)]), { self.inner.clear_with(f); } } impl HistogramFn for AtomicBucketInstant { fn record(&self, value: f64) { let now = Instant::now(); self.inner.push((value, now)); } }