From 392b6373c0856659803845807c60d930b3e85be6 Mon Sep 17 00:00:00 2001 From: Zak Cutner Date: Tue, 28 May 2024 17:09:19 +0100 Subject: [PATCH 1/2] Provide a method to clear a histogram Signed-off-by: Zak Cutner --- src/encoding/protobuf.rs | 29 +++++++++++++++++++++++++++++ src/metrics/histogram.rs | 12 ++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/encoding/protobuf.rs b/src/encoding/protobuf.rs index eef2731a..ffe17b3f 100644 --- a/src/encoding/protobuf.rs +++ b/src/encoding/protobuf.rs @@ -739,6 +739,35 @@ mod tests { ); assert_eq!(1, value.count); assert_eq!(11, value.buckets.len()); + assert_eq!(1u64, value.buckets.iter().map(|bucket| bucket.count).sum()); + } + _ => panic!("wrong value type"), + } + + histogram.clear(); + + let metric_set = encode(®istry).unwrap(); + + let family = metric_set.metric_families.first().unwrap(); + assert_eq!("my_histogram", family.name); + assert_eq!("My histogram.", family.help); + + assert_eq!( + openmetrics_data_model::MetricType::Histogram as i32, + extract_metric_type(&metric_set) + ); + + match extract_metric_point_value(&metric_set) { + openmetrics_data_model::metric_point::Value::HistogramValue(value) => { + assert_eq!( + Some(openmetrics_data_model::histogram_value::Sum::DoubleValue( + 0.0 + )), + value.sum + ); + assert_eq!(0, value.count); + assert_eq!(11, value.buckets.len()); + assert_eq!(0u64, value.buckets.iter().map(|bucket| bucket.count).sum()); } _ => panic!("wrong value type"), } diff --git a/src/metrics/histogram.rs b/src/metrics/histogram.rs index 66f4496d..b3922a62 100644 --- a/src/metrics/histogram.rs +++ b/src/metrics/histogram.rs @@ -101,6 +101,17 @@ impl Histogram { } } + /// Clears all observations. + pub fn clear(&self) { + let mut inner = self.inner.write(); + inner.sum = Default::default(); + inner.count = Default::default(); + + for (_, value) in &mut inner.buckets { + *value = 0; + } + } + pub(crate) fn get(&self) -> (f64, u64, MappedRwLockReadGuard>) { let inner = self.inner.read(); let sum = inner.sum; @@ -149,6 +160,7 @@ mod tests { fn histogram() { let histogram = Histogram::new(exponential_buckets(1.0, 2.0, 10)); histogram.observe(1.0); + histogram.clear(); } #[test] From 90f683650e46dc1c1ea46b554888639fb289708f Mon Sep 17 00:00:00 2001 From: Zak Cutner Date: Tue, 28 May 2024 17:15:41 +0100 Subject: [PATCH 2/2] Provide a method to reset a counter Signed-off-by: Zak Cutner --- src/metrics/counter.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/metrics/counter.rs b/src/metrics/counter.rs index c1c5e511..51f8e774 100644 --- a/src/metrics/counter.rs +++ b/src/metrics/counter.rs @@ -84,6 +84,11 @@ impl> Counter { self.value.inc_by(v) } + /// Resets the [`Counter`] to `0`, returning the previous value. + pub fn reset(&self) -> N { + self.value.reset() + } + /// Get the current value of the [`Counter`]. pub fn get(&self) -> N { self.value.get() @@ -110,6 +115,9 @@ pub trait Atomic { /// Increase the value. fn inc_by(&self, v: N) -> N; + /// Reset the value to `0`. + fn reset(&self) -> N; + /// Get the the value. fn get(&self) -> N; } @@ -124,6 +132,10 @@ impl Atomic for AtomicU64 { self.fetch_add(v, Ordering::Relaxed) } + fn reset(&self) -> u64 { + self.swap(Default::default(), Ordering::Relaxed) + } + fn get(&self) -> u64 { self.load(Ordering::Relaxed) } @@ -138,6 +150,10 @@ impl Atomic for AtomicU32 { self.fetch_add(v, Ordering::Relaxed) } + fn reset(&self) -> u32 { + self.swap(Default::default(), Ordering::Relaxed) + } + fn get(&self) -> u32 { self.load(Ordering::Relaxed) } @@ -164,6 +180,10 @@ impl Atomic for AtomicU64 { old_f64 } + fn reset(&self) -> f64 { + f64::from_bits(self.swap(Default::default(), Ordering::Relaxed)) + } + fn get(&self) -> f64 { f64::from_bits(self.load(Ordering::Relaxed)) } @@ -231,6 +251,14 @@ mod tests { assert_eq!(1, counter.get()); } + #[test] + fn inc_reset_and_get() { + let counter: Counter = Counter::default(); + assert_eq!(0, counter.inc()); + assert_eq!(1, counter.reset()); + assert_eq!(0, counter.get()); + } + #[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))] #[test] fn f64_stored_in_atomic_u64() {