1use crate::{
6 metrics::{is_enabled, Metric, ORDER},
7 registry::{DEFAULT_GROUPING_REGISTRY, DEFAULT_REGISTRY},
8};
9use std::sync::{atomic::AtomicUsize, Arc};
10
11pub trait Gauge<T: Default>: Send + Sync {
12 fn value(&self) -> T { T::default() }
13 fn update(&self, _value: T) {}
14}
15
16struct NoopGauge;
17impl<T: Default> Gauge<T> for NoopGauge {}
18
19#[macro_export]
20macro_rules! construct_gauge {
21 ($name:ident, $value_type:ty, $data_type:ty) => {
22 #[derive(Default)]
23 pub struct $name {
24 value: $value_type,
25 }
26
27 impl $name {
28 pub fn register(name: &str) -> Arc<dyn Gauge<$data_type>> {
29 if !is_enabled() {
30 return Arc::new(NoopGauge);
31 }
32
33 let gauge = Arc::new($name::default());
34 DEFAULT_REGISTRY
35 .write()
36 .register(name.into(), gauge.clone());
37
38 gauge
39 }
40
41 pub fn register_with_group(
42 group: &str, name: &str,
43 ) -> Arc<dyn Gauge<$data_type>> {
44 if !is_enabled() {
45 return Arc::new(NoopGauge);
46 }
47
48 let gauge = Arc::new($name::default());
49 DEFAULT_GROUPING_REGISTRY.write().register(
50 group.into(),
51 name.into(),
52 gauge.clone(),
53 );
54
55 gauge
56 }
57 }
58
59 impl Gauge<$data_type> for $name {
60 fn value(&self) -> usize { self.value.load(ORDER) }
61
62 fn update(&self, value: usize) { self.value.store(value, ORDER); }
63 }
64
65 impl Metric for $name {
66 fn get_type(&self) -> &str { "Gauge" }
67 }
68 };
69}
70
71construct_gauge!(GaugeUsize, AtomicUsize, usize);