prometheus/
pulling_gauge.rs
1use std::{collections::HashMap, fmt, sync::Arc};
2
3use crate::{
4 core::Collector,
5 proto::{Gauge, Metric, MetricFamily, MetricType},
6};
7
8#[derive(Clone)]
29pub struct PullingGauge {
30 desc: crate::core::Desc,
31 value: Arc<Box<dyn Fn() -> f64 + Send + Sync>>,
32}
33
34impl fmt::Debug for PullingGauge {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 f.debug_struct("PullingGauge")
37 .field("desc", &self.desc)
38 .field("value", &"<opaque>")
39 .finish()
40 }
41}
42
43impl PullingGauge {
44 pub fn new<S1: Into<String>, S2: Into<String>>(
46 name: S1,
47 help: S2,
48 value: Box<dyn Fn() -> f64 + Send + Sync>,
49 ) -> crate::Result<Self> {
50 Ok(PullingGauge {
51 value: Arc::new(value),
52 desc: crate::core::Desc::new(name.into(), help.into(), Vec::new(), HashMap::new())?,
53 })
54 }
55
56 fn metric(&self) -> Metric {
57 let mut gauge = Gauge::default();
58 let getter = &self.value;
59 gauge.set_value(getter());
60
61 let mut metric = Metric::default();
62 metric.set_gauge(gauge);
63
64 metric
65 }
66}
67
68impl Collector for PullingGauge {
69 fn desc(&self) -> Vec<&crate::core::Desc> {
70 vec![&self.desc]
71 }
72
73 fn collect(&self) -> Vec<crate::proto::MetricFamily> {
74 let mut m = MetricFamily::default();
75 m.set_name(self.desc.fq_name.clone());
76 m.set_help(self.desc.help.clone());
77 m.set_field_type(MetricType::GAUGE);
78 m.set_metric(from_vec!(vec![self.metric()]));
79 vec![m]
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use crate::metrics::Collector;
87
88 #[test]
89 fn test_pulling_gauge() {
90 const VALUE: f64 = 10.0;
91
92 let gauge =
93 PullingGauge::new("test_gauge", "Purely for testing", Box::new(|| VALUE)).unwrap();
94
95 let metrics = gauge.collect();
96 assert_eq!(metrics.len(), 1);
97
98 assert_eq!(VALUE, metrics[0].get_metric()[0].get_gauge().get_value());
99 }
100}