Skip to content

Commit cb64ace

Browse files
committed
Prototype of metrics expiry
Signed-off-by: John Howard <john.howard@solo.io>
1 parent 12923ca commit cb64ace

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ http-body-util = "0.1.1"
4343
[build-dependencies]
4444
prost-build = { version = "0.12.0", optional = true }
4545

46+
[[example]]
47+
name = "prune"
48+
4649
[[bench]]
4750
name = "baseline"
4851
harness = false

examples/prune.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use prometheus_client::encoding::{text::encode, EncodeMetric, MetricEncoder};
2+
use prometheus_client::metrics::counter::Atomic;
3+
use prometheus_client::metrics::family::Family;
4+
use prometheus_client::metrics::{MetricType, TypedMetric};
5+
use prometheus_client::registry::Registry;
6+
use prometheus_client_derive_encode::EncodeLabelSet;
7+
use std::fmt::Error;
8+
use std::sync::atomic::AtomicU64;
9+
use std::sync::{Arc, Mutex};
10+
use std::thread;
11+
use std::time::Duration;
12+
use tokio::time::Instant;
13+
14+
#[derive(Default, Debug)]
15+
struct MyCounter {
16+
value: Arc<AtomicU64>,
17+
last_access: Arc<Mutex<Option<Instant>>>,
18+
}
19+
20+
impl TypedMetric for MyCounter {}
21+
22+
impl MyCounter {
23+
pub fn get(&self) -> u64 {
24+
self.value.get()
25+
}
26+
pub fn inc(&self) -> u64 {
27+
let mut last = self.last_access.lock().unwrap();
28+
*last = Some(Instant::now());
29+
self.value.inc()
30+
}
31+
}
32+
33+
impl EncodeMetric for MyCounter {
34+
fn encode(&self, mut encoder: MetricEncoder) -> Result<(), Error> {
35+
encoder.encode_counter::<(), _, u64>(&self.get(), None)
36+
}
37+
38+
fn metric_type(&self) -> MetricType {
39+
todo!()
40+
}
41+
}
42+
43+
#[derive(Clone, Hash, Default, Debug, PartialEq, Eq, EncodeLabelSet)]
44+
struct Labels {
45+
name: String,
46+
}
47+
48+
fn main() {
49+
let mut registry = Registry::default();
50+
51+
let metric: Family<Labels, MyCounter> = Family::default();
52+
registry.register("my_custom_metric", "test", metric.clone());
53+
metric
54+
.get_or_create(&Labels {
55+
name: "apple".to_string(),
56+
})
57+
.inc();
58+
metric
59+
.get_or_create(&Labels {
60+
name: "banana".to_string(),
61+
})
62+
.inc();
63+
64+
let mut encoded = String::new();
65+
encode(&mut encoded, &registry).unwrap();
66+
67+
println!("Scrape output:\n{}", encoded);
68+
thread::sleep(Duration::from_secs(1));
69+
metric
70+
.get_or_create(&Labels {
71+
name: "banana".to_string(),
72+
})
73+
.inc();
74+
let now = Instant::now();
75+
metric.retain(|a, b| {
76+
let last = b.last_access.lock().unwrap().unwrap();
77+
now.saturating_duration_since(last) > Duration::from_secs(1)
78+
});
79+
80+
let mut encoded = String::new();
81+
encode(&mut encoded, &registry).unwrap();
82+
83+
println!("Scrape output:\n{}", encoded);
84+
}

src/metrics/family.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ impl<S: Clone + std::hash::Hash + Eq, M, C: MetricConstructor<M>> Family<S, M, C
288288
self.metrics.write().clear()
289289
}
290290

291+
/// retain
292+
pub fn retain<F>(&self, f: F)
293+
where
294+
F: FnMut(&S, &mut M) -> bool,
295+
{
296+
self.metrics.write().retain(f)
297+
}
298+
291299
pub(crate) fn read(&self) -> RwLockReadGuard<HashMap<S, M>> {
292300
self.metrics.read()
293301
}

0 commit comments

Comments
 (0)