From 9bd6291c2ba97f40a26c7ead5493b0cd38c6d01b Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Mon, 19 Sep 2022 17:32:36 -0500 Subject: [PATCH] feature: Impl TypedMetric for WithExemplar types, so a metric can use both families and exemplars Fixes issue #95. Signed-off-by: Adam Chalmers --- CHANGELOG.md | 2 ++ examples/families-exemplars.rs | 47 ++++++++++++++++++++++++++++++++++ src/metrics/exemplar.rs | 9 +++++++ 3 files changed, 58 insertions(+) create mode 100644 examples/families-exemplars.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index a554904b..0532a102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 set from a family. See [PR 85]. - Added a `clear` method to `Family` to allow the removal of all label sets from a family. See [PR 85]. +- Impl `TypedMetric` for `CounterWithExemplar` and `HistogramWithExemplar`, so that they can be used with `Family`. See [PR 96]. ### Changed @@ -19,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [PR 83]: https://github.com/prometheus/client_rust/pull/83 [PR 85]: https://github.com/prometheus/client_rust/pull/85 +[PR 96]: https://github.com/prometheus/client_rust/pull/96 ## [0.18.0] diff --git a/examples/families-exemplars.rs b/examples/families-exemplars.rs new file mode 100644 index 00000000..eab43f72 --- /dev/null +++ b/examples/families-exemplars.rs @@ -0,0 +1,47 @@ +use prometheus_client::{ + encoding::text::encode, + metrics::{exemplar::HistogramWithExemplars, family::Family, histogram::exponential_buckets}, + registry::Registry, +}; +use prometheus_client_derive_encode::Encode; + +fn main() { + // Create a metric registry. + let mut registry = ::default(); + + // Metric will be used something like this: + // latency_bucket{result="success",le="0.00256"} 27300 # {trace_id="3a2f90c9f80b894f"} 0.001345422 1.6188203823429482e+09 + let latency: Family> = + Family::new_with_constructor(|| { + HistogramWithExemplars::new(exponential_buckets(1.0, 2.0, 10)) + }); + + // Register metrics. + registry.register("latency", "help text goes here", Box::new(latency.clone())); + + latency + .get_or_create(&ResultLabel { + result: "success".to_owned(), + }) + .observe( + 0.001345422, + Some(TraceLabel { + trace_id: "3a2f90c9f80b894f".to_owned(), + }), + ); + + let mut buf = Vec::new(); + encode(&mut buf, ®istry).unwrap(); + let line = std::str::from_utf8(buf.as_slice()).unwrap().to_string(); + println!("{line}"); +} + +#[derive(Clone, Hash, PartialEq, Eq, Encode, Debug, Default)] +pub struct ResultLabel { + pub result: String, +} + +#[derive(Clone, Hash, PartialEq, Eq, Encode, Debug, Default)] +pub struct TraceLabel { + pub trace_id: String, +} diff --git a/src/metrics/exemplar.rs b/src/metrics/exemplar.rs index 84462003..1015d7f2 100644 --- a/src/metrics/exemplar.rs +++ b/src/metrics/exemplar.rs @@ -4,6 +4,7 @@ use super::counter::{self, Counter}; use super::histogram::Histogram; +use super::{MetricType, TypedMetric}; use parking_lot::{MappedRwLockReadGuard, RwLock, RwLockReadGuard}; use std::collections::HashMap; #[cfg(any(target_arch = "mips", target_arch = "powerpc"))] @@ -37,6 +38,10 @@ pub struct CounterWithExemplar { pub(crate) inner: Arc>>, } +impl TypedMetric for CounterWithExemplar { + const TYPE: MetricType = MetricType::Counter; +} + /// Open Metrics [`Counter`] with an [`Exemplar`] to both measure discrete /// events and track references to data outside of the metric set. #[cfg(any(target_arch = "mips", target_arch = "powerpc"))] @@ -128,6 +133,10 @@ pub struct HistogramWithExemplars { pub(crate) inner: Arc>>, } +impl TypedMetric for HistogramWithExemplars { + const TYPE: MetricType = MetricType::Histogram; +} + impl Clone for HistogramWithExemplars { fn clone(&self) -> Self { Self {