From 2c3afbae392b7ce5ada3998c0e7e1847306fc27a Mon Sep 17 00:00:00 2001 From: katelyn martin Date: Tue, 2 Sep 2025 00:00:00 +0000 Subject: [PATCH 1/3] feat: introduce `test-util` feature flag for background, see discussion in #242: > > Would you be amenable to feature-gating these public helpers behind > > a `test-util` feature? This is a pretty common approach we've seen > > in other crates. > > That sounds reasonable to me. Contribution welcome. Thanks. Please > point out very prominently that we might break any of those APIs in > a patch release. \- this commit introduces a `test-util` feature flag. this feature flag will function as a gate for additional interfaces, such as accessors to read the value of a histogram, that facilitate integration tests inspecting metrics. comments note that any forthcoming interfaces included by this feature are not subject to stability guarantees. Signed-off-by: katelyn martin --- Cargo.toml | 7 +++++++ src/lib.rs | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index a35d1457..13a7e3bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,13 @@ documentation = "https://docs.rs/prometheus-client" default = [] protobuf = ["dep:prost", "dep:prost-types", "dep:prost-build"] +# This feature provides additional APIs for testing downstream code using +# `prometheus-client`. +# +# Note: Interfaces gated by this feature flag are not subject to stability +# guarantees and may be changed or removed in patch releases. +test-util = [] + [workspace] members = ["derive-encode"] diff --git a/src/lib.rs b/src/lib.rs index cfff6238..9aab12f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,6 +77,12 @@ //! ``` //! See [examples] directory for more. //! +//! # Features +//! +//! The `test-util` gates additional APIs, such as accessors, to facilitate integration and unit +//! testing of metrics. Note that APIs gated by this feature flag are not subject to stability +//! guarantees and may be changed or removed in patch releases. +//! //! [examples]: https://github.com/prometheus/client_rust/tree/master/examples pub mod collector; From 4e1d7730b14a07dc226d39b4503273698e646cbd Mon Sep 17 00:00:00 2001 From: katelyn martin Date: Mon, 13 Oct 2025 00:00:00 +0000 Subject: [PATCH 2/3] feat(metrics/histogram): `count()` and `sum()` accessors fixes #241. this commit introduces two new public methods to `Histogram`; `sum()` and `count()` return the sum of all observations and the number of observations made, respectively. Signed-off-by: katelyn martin --- src/metrics/histogram.rs | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/metrics/histogram.rs b/src/metrics/histogram.rs index 1f5e4d96..8a4a28ad 100644 --- a/src/metrics/histogram.rs +++ b/src/metrics/histogram.rs @@ -81,6 +81,18 @@ impl Histogram { self.observe_and_bucket(v); } + /// Returns the current sum of all observations. + #[cfg(any(test, feature = "test-util"))] + pub fn sum(&self) -> f64 { + self.inner.read().sum + } + + /// Returns the current number of observations. + #[cfg(any(test, feature = "test-util"))] + pub fn count(&self) -> u64 { + self.inner.read().count + } + /// Observes the given value, returning the index of the first bucket the /// value is added to. /// @@ -212,4 +224,53 @@ mod tests { let res = exponential_buckets_range(0.0, 32.0, 6).collect::>(); assert!(res.is_empty()); } + + /// Checks that [`Histogram::count()`] works properly. + #[test] + fn count() { + let histogram = Histogram::new([1.0_f64, 2.0, 3.0, 4.0, 5.0]); + assert_eq!( + histogram.count(), + 0, + "histogram has zero observations when instantiated" + ); + + histogram.observe(1.0); + assert_eq!(histogram.count(), 1, "histogram has one observation"); + + histogram.observe(2.5); + assert_eq!(histogram.count(), 2, "histogram has two observations"); + + histogram.observe(6.0); + assert_eq!(histogram.count(), 3, "histogram has three observations"); + } + + /// Checks that [`Histogram::sum()`] works properly. + #[test] + fn sum() { + const BUCKETS: [f64; 3] = [10.0, 100.0, 1000.0]; + let histogram = Histogram::new(BUCKETS); + assert_eq!( + histogram.sum(), + 0.0, + "histogram sum is zero when instantiated" + ); + + histogram.observe(3.0); // 3 + 4 + 15 + 101 = 123 + histogram.observe(4.0); + histogram.observe(15.0); + histogram.observe(101.0); + assert_eq!( + histogram.sum(), + 123.0, + "histogram sum records accurate sum of observations" + ); + + histogram.observe(1111.0); + assert_eq!( + histogram.sum(), + 1234.0, + "histogram sum records accurate sum of observations" + ); + } } From 603395ccbca735fbf9139c57e627f6c714b1dd33 Mon Sep 17 00:00:00 2001 From: katelyn martin Date: Mon, 3 Nov 2025 00:00:00 +0000 Subject: [PATCH 3/3] chore: changelog entry Signed-off-by: katelyn martin --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4afd4ff1..fa465225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,9 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `EncodeGaugeValue` would not error when encoding some `u64`s that don't fit in a `i64`. See [PR 281]. - Filter out empty metric families, to match the go client. See [PR 279]. +- `Histogram` now exposes `count()` and `sum()` methods when the `test-util` + feature is enabled. See [PR 242]. [PR 279]: https://github.com/prometheus/client_rust/pull/279 [PR 281]: https://github.com/prometheus/client_rust/pull/281 +[PR 242]: https://github.com/prometheus/client_rust/pull/242 ## [0.24.0]