Skip to content

Commit 8b462b1

Browse files
authored
Add PullingGauge (#405)
Signed-off-by: Jan Berktold <[email protected]> Signed-off-by: Jan Berktold <[email protected]>
1 parent 422b3af commit 8b462b1

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ mod errors;
158158
mod gauge;
159159
mod histogram;
160160
mod metrics;
161+
mod pulling_gauge;
161162
#[cfg(feature = "push")]
162163
mod push;
163164
mod registry;
@@ -219,6 +220,7 @@ pub use self::histogram::DEFAULT_BUCKETS;
219220
pub use self::histogram::{exponential_buckets, linear_buckets};
220221
pub use self::histogram::{Histogram, HistogramOpts, HistogramTimer, HistogramVec};
221222
pub use self::metrics::Opts;
223+
pub use self::pulling_gauge::PullingGauge;
222224
#[cfg(feature = "push")]
223225
pub use self::push::{
224226
hostname_grouping_key, push_add_collector, push_add_metrics, push_collector, push_metrics,

src/pulling_gauge.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use std::{collections::HashMap, fmt, sync::Arc};
2+
3+
use crate::{
4+
core::Collector,
5+
proto::{Gauge, Metric, MetricFamily, MetricType},
6+
};
7+
use protobuf::RepeatedField;
8+
9+
/// A [Gauge] that returns the value from a provided function on every collect run.
10+
///
11+
/// This metric is the equivalant of Go's
12+
/// <https://pkg.go.dev/github.com/prometheus/[email protected]/prometheus#GaugeFunc>
13+
///
14+
/// # Examples
15+
/// ```
16+
/// # use prometheus::{Registry, PullingGauge};
17+
/// # // We are stubbing out std::thread::available_parallelism since it's not available in the
18+
/// # // oldest Rust version that we support.
19+
/// # fn available_parallelism() -> f64 { 0.0 }
20+
///
21+
/// let registry = Registry::new();
22+
/// let gauge = PullingGauge::new(
23+
/// "available_parallelism",
24+
/// "The available parallelism, usually the numbers of logical cores.",
25+
/// Box::new(|| available_parallelism())
26+
/// ).unwrap();
27+
/// registry.register(Box::new(gauge));
28+
/// ```
29+
#[derive(Clone)]
30+
pub struct PullingGauge {
31+
desc: crate::core::Desc,
32+
value: Arc<Box<dyn Fn() -> f64 + Send + Sync>>,
33+
}
34+
35+
impl fmt::Debug for PullingGauge {
36+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37+
f.debug_struct("PullingGauge")
38+
.field("desc", &self.desc)
39+
.field("value", &"<opaque>")
40+
.finish()
41+
}
42+
}
43+
44+
impl PullingGauge {
45+
/// Create a new [`PullingGauge`].
46+
pub fn new<S1: Into<String>, S2: Into<String>>(
47+
name: S1,
48+
help: S2,
49+
value: Box<dyn Fn() -> f64 + Send + Sync>,
50+
) -> crate::Result<Self> {
51+
Ok(PullingGauge {
52+
value: Arc::new(value),
53+
desc: crate::core::Desc::new(name.into(), help.into(), Vec::new(), HashMap::new())?,
54+
})
55+
}
56+
57+
fn metric(&self) -> Metric {
58+
let mut gauge = Gauge::default();
59+
let getter = &self.value;
60+
gauge.set_value(getter());
61+
62+
let mut metric = Metric::default();
63+
metric.set_gauge(gauge);
64+
65+
metric
66+
}
67+
}
68+
69+
impl Collector for PullingGauge {
70+
fn desc(&self) -> Vec<&crate::core::Desc> {
71+
vec![&self.desc]
72+
}
73+
74+
fn collect(&self) -> Vec<crate::proto::MetricFamily> {
75+
let mut m = MetricFamily::default();
76+
m.set_name(self.desc.fq_name.clone());
77+
m.set_help(self.desc.help.clone());
78+
m.set_field_type(MetricType::GAUGE);
79+
m.set_metric(RepeatedField::from_vec(vec![self.metric()]));
80+
vec![m]
81+
}
82+
}
83+
84+
#[cfg(test)]
85+
mod tests {
86+
use super::*;
87+
use crate::metrics::Collector;
88+
89+
#[test]
90+
fn test_pulling_gauge() {
91+
const VALUE: f64 = 10.0;
92+
93+
let gauge =
94+
PullingGauge::new("test_gauge", "Purely for testing", Box::new(|| VALUE)).unwrap();
95+
96+
let metrics = gauge.collect();
97+
assert_eq!(metrics.len(), 1);
98+
99+
assert_eq!(VALUE, metrics[0].get_metric()[0].get_gauge().get_value());
100+
}
101+
}

0 commit comments

Comments
 (0)