Skip to content

Commit

Permalink
metrics-exporter-prometheus: fix recent metrics being removed by idle…
Browse files Browse the repository at this point in the history
… timeout logic (#264)

* metrics-exporter-prometheus: fix issue with recent metrics being removed by idle timeout logic

Signed-off-by: Toby Lawrence <[email protected]>
  • Loading branch information
tobz authored Jan 5, 2022
1 parent e10cbbc commit a5d5512
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 5 deletions.
49 changes: 49 additions & 0 deletions metrics-exporter-prometheus/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,55 @@ mod tests {
assert_eq!(rendered, expected_after);
}

#[test]
fn test_idle_timeout_doesnt_remove_recents() {
let (clock, mock) = Clock::mock();

let recorder = PrometheusBuilder::new()
.idle_timeout(MetricKindMask::ALL, Some(Duration::from_secs(10)))
.build_with_clock(clock);

let key = Key::from_name("basic_counter");
let counter1 = recorder.register_counter(&key);
counter1.increment(42);

let key = Key::from_name("basic_gauge");
let gauge1 = recorder.register_gauge(&key);
gauge1.set(-3.14);

let handle = recorder.handle();
let rendered = handle.render();
let expected = concat!(
"# TYPE basic_counter counter\n",
"basic_counter 42\n\n",
"# TYPE basic_gauge gauge\n",
"basic_gauge -3.14\n\n",
);

assert_eq!(rendered, expected);

mock.increment(Duration::from_secs(9));
let rendered = handle.render();
assert_eq!(rendered, expected);

let expected_second = concat!(
"# TYPE basic_counter counter\n",
"basic_counter 42\n\n",
"# TYPE basic_gauge gauge\n",
"basic_gauge -3.14\n\n",
);
let rendered = handle.render();
assert_eq!(rendered, expected_second);

counter1.increment(1);

let expected_after = concat!("# TYPE basic_counter counter\n", "basic_counter 43\n\n",);

mock.increment(Duration::from_secs(2));
let rendered = handle.render();
assert_eq!(rendered, expected_after);
}

#[test]
pub fn test_global_labels() {
let recorder = PrometheusBuilder::new()
Expand Down
6 changes: 3 additions & 3 deletions metrics-exporter-prometheus/src/recorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,15 @@ impl Recorder for PrometheusRecorder {
}

fn register_counter(&self, key: &Key) -> Counter {
self.inner.registry.get_or_create_counter(key, |c| c.get_inner().clone().into())
self.inner.registry.get_or_create_counter(key, |c| c.clone().into())
}

fn register_gauge(&self, key: &Key) -> Gauge {
self.inner.registry.get_or_create_gauge(key, |c| c.get_inner().clone().into())
self.inner.registry.get_or_create_gauge(key, |c| c.clone().into())
}

fn register_histogram(&self, key: &Key) -> Histogram {
self.inner.registry.get_or_create_histogram(key, |c| c.get_inner().clone().into())
self.inner.registry.get_or_create_histogram(key, |c| c.clone().into())
}
}

Expand Down
31 changes: 29 additions & 2 deletions metrics-util/src/recency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ use crate::registry::Primitives;
use crate::StandardPrimitives;
use crate::{kind::MetricKindMask, MetricKind, Registry};

use metrics::{CounterFn, GaugeFn, HistogramFn, Key};
use metrics::{Counter, CounterFn, Gauge, GaugeFn, Histogram, HistogramFn, Key};
use parking_lot::Mutex;
use quanta::{Clock, Instant};

/// The generation of a metric.
///
/// Generations are opaque and are not meant to be used directly, but meant to be used as a
/// comparison amongst each other in terms of ordering.
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Generation(usize);

/// Generation tracking for a metric.
Expand Down Expand Up @@ -126,6 +126,33 @@ where
}
}

impl<T> From<Generational<T>> for Counter
where
T: CounterFn + Send + Sync + 'static,
{
fn from(inner: Generational<T>) -> Self {
Counter::from_arc(Arc::new(inner))
}
}

impl<T> From<Generational<T>> for Gauge
where
T: GaugeFn + Send + Sync + 'static,
{
fn from(inner: Generational<T>) -> Self {
Gauge::from_arc(Arc::new(inner))
}
}

impl<T> From<Generational<T>> for Histogram
where
T: HistogramFn + Send + Sync + 'static,
{
fn from(inner: Generational<T>) -> Self {
Histogram::from_arc(Arc::new(inner))
}
}

/// Primitives for tracking the generation of metrics.
///
/// [`Generational<T>`] explains more about the purpose of generation tracking.
Expand Down

0 comments on commit a5d5512

Please sign in to comment.