Skip to content

Commit

Permalink
feature: Impl TypedMetric for WithExemplar types, so a metric can use…
Browse files Browse the repository at this point in the history
… both families and exemplars

Fixes issue #95.

Signed-off-by: Adam Chalmers <adam.s.chalmers@gmail.com>
  • Loading branch information
adamchalmers committed Sep 26, 2022
1 parent 12c1de5 commit 7150bba
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ 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

- Move`Encode` trait from `prometheus_client::encoding::text` to `prometheus_client::encoding`. See [PR 83].

[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]

Expand Down
70 changes: 70 additions & 0 deletions src/metrics/exemplar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand Down Expand Up @@ -31,12 +32,45 @@ pub struct Exemplar<S, V> {
/// counter_with_exemplar.inc_by(1, Some(vec![("user_id".to_string(), "42".to_string())]));
/// let _value: (u64, _) = counter_with_exemplar.get();
/// ```
/// You can also use exemplars with families. Just wrap the exemplar in a Family.
/// ```
/// # use prometheus_client::metrics::exemplar::CounterWithExemplar;
/// # use prometheus_client::metrics::histogram::exponential_buckets;
/// # use prometheus_client::metrics::family::Family;
/// # use prometheus_client_derive_encode::Encode;
/// #[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,
/// }
///
/// let latency: Family<ResultLabel, CounterWithExemplar<TraceLabel>> = Family::default();
///
/// latency
/// .get_or_create(&ResultLabel {
/// result: "success".to_owned(),
/// })
/// .inc_by(
/// 1,
/// Some(TraceLabel {
/// trace_id: "3a2f90c9f80b894f".to_owned(),
/// }),
/// );
/// ```
#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
#[derive(Debug)]
pub struct CounterWithExemplar<S, N = u64, A = AtomicU64> {
pub(crate) inner: Arc<RwLock<CounterWithExemplarInner<S, N, A>>>,
}

impl<S> TypedMetric for CounterWithExemplar<S> {
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"))]
Expand Down Expand Up @@ -122,12 +156,48 @@ impl<S, N: Clone, A: counter::Atomic<N>> CounterWithExemplar<S, N, A> {
/// let histogram = HistogramWithExemplars::new(exponential_buckets(1.0, 2.0, 10));
/// histogram.observe(4.2, Some(vec![("user_id".to_string(), "42".to_string())]));
/// ```
/// You can also use exemplars with families. Just wrap the exemplar in a Family.
/// ```
/// # use prometheus_client::metrics::exemplar::HistogramWithExemplars;
/// # use prometheus_client::metrics::histogram::exponential_buckets;
/// # use prometheus_client::metrics::family::Family;
/// # use prometheus_client_derive_encode::Encode;
/// #[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,
/// }
///
/// let latency: Family<ResultLabel, HistogramWithExemplars<TraceLabel>> =
/// Family::new_with_constructor(|| {
/// HistogramWithExemplars::new(exponential_buckets(1.0, 2.0, 10))
/// });
///
/// latency
/// .get_or_create(&ResultLabel {
/// result: "success".to_owned(),
/// })
/// .observe(
/// 0.001345422,
/// Some(TraceLabel {
/// trace_id: "3a2f90c9f80b894f".to_owned(),
/// }),
/// );
/// ```
#[derive(Debug)]
pub struct HistogramWithExemplars<S> {
// TODO: Not ideal, as Histogram has a Mutex as well.
pub(crate) inner: Arc<RwLock<HistogramWithExemplarsInner<S>>>,
}

impl<S> TypedMetric for HistogramWithExemplars<S> {
const TYPE: MetricType = MetricType::Histogram;
}

impl<S> Clone for HistogramWithExemplars<S> {
fn clone(&self) -> Self {
Self {
Expand Down

0 comments on commit 7150bba

Please sign in to comment.