avalanche_types/subnet/rpc/
metrics.rs

1//! Support for Prometheus metrics.
2use crate::proto::pb::io::prometheus::client::{
3    Bucket, Counter, Gauge, Histogram, LabelPair, Metric, MetricFamily, Quantile, Summary,
4};
5
6/// A list of LabelPair
7#[derive(Clone, Debug)]
8pub struct LabelPairs {
9    pub lps: Vec<LabelPair>,
10}
11
12impl From<&[prometheus::proto::LabelPair]> for LabelPairs {
13    fn from(item: &[prometheus::proto::LabelPair]) -> Self {
14        let mut lps = Vec::with_capacity(item.len());
15        for lp in item.iter() {
16            lps.push(LabelPair::from(lp));
17        }
18        Self { lps }
19    }
20}
21
22impl From<&prometheus::proto::LabelPair> for LabelPair {
23    fn from(item: &prometheus::proto::LabelPair) -> Self {
24        LabelPair {
25            name: Some(item.get_name().to_owned()),
26            value: Some(item.get_value().to_owned()),
27        }
28    }
29}
30
31impl From<&prometheus::proto::Gauge> for Gauge {
32    fn from(item: &prometheus::proto::Gauge) -> Self {
33        Gauge {
34            value: Some(item.get_value()),
35        }
36    }
37}
38
39impl From<&prometheus::proto::Counter> for Counter {
40    fn from(item: &prometheus::proto::Counter) -> Self {
41        Counter {
42            value: Some(item.get_value()),
43            exemplar: None,
44        }
45    }
46}
47
48impl From<&prometheus::proto::Histogram> for Histogram {
49    fn from(item: &prometheus::proto::Histogram) -> Self {
50        Histogram {
51            bucket: Buckets::from(item.get_bucket()).bs,
52            sample_count: Some(item.get_sample_count()),
53            sample_sum: Some(item.get_sample_sum()),
54        }
55    }
56}
57
58impl From<&prometheus::proto::Bucket> for Bucket {
59    fn from(item: &prometheus::proto::Bucket) -> Self {
60        Bucket {
61            cumulative_count: Some(item.get_cumulative_count()),
62            upper_bound: Some(item.get_upper_bound()),
63            exemplar: None,
64        }
65    }
66}
67
68/// A list of Bucket
69#[derive(Clone, Debug)]
70pub struct Buckets {
71    pub bs: Vec<Bucket>,
72}
73
74impl From<&[prometheus::proto::Bucket]> for Buckets {
75    fn from(item: &[prometheus::proto::Bucket]) -> Self {
76        let mut bs = Vec::with_capacity(item.len());
77        for b in item.iter() {
78            bs.push(Bucket::from(b));
79        }
80        Self { bs }
81    }
82}
83
84impl From<&prometheus::proto::Summary> for Summary {
85    fn from(item: &prometheus::proto::Summary) -> Self {
86        Summary {
87            sample_sum: Some(item.get_sample_sum()),
88            sample_count: Some(item.get_sample_count()),
89            quantile: Quantiles::from(item.get_quantile()).qs,
90        }
91    }
92}
93
94impl From<&prometheus::proto::Quantile> for Quantile {
95    fn from(item: &prometheus::proto::Quantile) -> Self {
96        Quantile {
97            quantile: Some(item.get_quantile()),
98            value: Some(item.get_value()),
99        }
100    }
101}
102
103/// A list of Quantile
104#[derive(Clone, Debug)]
105pub struct Quantiles {
106    pub qs: Vec<Quantile>,
107}
108
109impl From<&[prometheus::proto::Quantile]> for Quantiles {
110    fn from(item: &[prometheus::proto::Quantile]) -> Self {
111        let mut qs = Vec::with_capacity(item.len());
112        for q in item.iter() {
113            qs.push(Quantile::from(q));
114        }
115        Self { qs }
116    }
117}
118
119impl From<&prometheus::proto::Metric> for Metric {
120    fn from(item: &prometheus::proto::Metric) -> Self {
121        Metric {
122            label: LabelPairs::from(item.get_label()).lps,
123            counter: Some(Counter::from(item.get_counter())),
124            gauge: Some(Gauge::from(item.get_gauge())),
125            histogram: Some(Histogram::from(item.get_histogram())),
126            summary: Some(Summary::from(item.get_summary())),
127            timestamp_ms: Some(item.get_timestamp_ms()),
128            untyped: None, // deprecated
129        }
130    }
131}
132
133/// A list of MetricFamily
134#[derive(Clone, Debug)]
135pub struct MetricsFamilies {
136    pub mfs: Vec<MetricFamily>,
137}
138
139impl From<&Vec<prometheus::proto::MetricFamily>> for MetricsFamilies {
140    fn from(item: &Vec<prometheus::proto::MetricFamily>) -> Self {
141        let mut mfs = Vec::with_capacity(item.len());
142        for mf in item.iter() {
143            let mut metric = Vec::new();
144            for m in mf.get_metric().iter() {
145                metric.push(Metric::from(m));
146            }
147            mfs.push(MetricFamily {
148                name: Some(mf.get_name().to_owned()),
149                help: Some(mf.get_help().to_owned()),
150                r#type: Some(mf.get_field_type() as i32),
151                metric,
152            });
153        }
154        Self { mfs }
155    }
156}
157
158#[test]
159#[ignore]
160fn test_gather_process() {
161    let families = [
162        "process_cpu_seconds_total",
163        "process_max_fds",
164        "process_open_fds",
165        "process_resident_memory_bytes",
166        "process_start_time_seconds",
167        "process_cpu_seconds_total",
168        "process_virtual_memory_bytes",
169    ];
170
171    let metric_families = MetricsFamilies::from(&prometheus::gather()).mfs;
172    if !metric_families.is_empty() {
173        for (i, family) in families.iter().enumerate() {
174            if let Some(name) = &metric_families[i].name {
175                assert_eq!(name, family);
176            } else {
177                panic!("expected some {} found none", family)
178            }
179        }
180    }
181}