mithril_aggregator/metrics/
service.rs

1use std::collections::HashMap;
2
3use mithril_metric::{build_metrics_service, MetricCounterWithLabels, MetricsServiceExporter};
4
5use mithril_metric::metric::{MetricCollector, MetricCounter};
6use prometheus::proto::{LabelPair, MetricFamily};
7
8static ORIGIN_TAG_LABEL: &str = "origin_tag";
9
10build_metrics_service!(
11    MetricsService,
12
13    certificate_detail_total_served_since_startup:MetricCounterWithLabels(
14        "certificate_detail_total_served_since_startup",
15        "Number of certificate details served since startup on a Mithril aggregator node",
16        &[ORIGIN_TAG_LABEL]
17    ),
18    artifact_detail_cardano_immutable_files_full_total_served_since_startup:MetricCounterWithLabels(
19        "mithril_aggregator_artifact_detail_cardano_db_total_served_since_startup",
20        "Number of Cardano immutable files full artifact details served since startup on a Mithril aggregator node",
21        &[ORIGIN_TAG_LABEL]
22    ),
23    cardano_immutable_files_full_total_restoration_since_startup:MetricCounterWithLabels(
24        "mithril_aggregator_cardano_db_total_restoration_since_startup",
25        "Number of Cardano immutable files full restorations since startup on a Mithril aggregator node",
26        &[ORIGIN_TAG_LABEL]
27    ),
28    cardano_database_immutable_files_restored_since_startup:MetricCounterWithLabels(
29        "mithril_aggregator_cardano_db_immutable_files_restored_since_startup",
30        "Number of Cardano immutable files restored since startup on a Mithril aggregator node",
31        &[ORIGIN_TAG_LABEL]
32    ),
33    cardano_database_ancillary_files_restored_since_startup:MetricCounterWithLabels(
34        "mithril_aggregator_cardano_db_ancillary_files_restored_since_startup",
35        "Number of Cardano ancillary files restored since startup on a Mithril aggregator node",
36        &[ORIGIN_TAG_LABEL]
37    ),
38    cardano_database_complete_restoration_since_startup:MetricCounterWithLabels(
39        "mithril_aggregator_cardano_db_complete_restoration_since_startup",
40        "Number of complete Cardano database restoration since startup on a Mithril aggregator node",
41        &[ORIGIN_TAG_LABEL]
42    ),
43    cardano_database_partial_restoration_since_startup:MetricCounterWithLabels(
44        "mithril_aggregator_cardano_db_partial_restoration_since_startup",
45        "Number of partial Cardano database restoration since startup on a Mithril aggregator node",
46        &[ORIGIN_TAG_LABEL]
47    ),
48    artifact_detail_cardano_database_total_served_since_startup:MetricCounterWithLabels(
49        "mithril_aggregator_artifact_detail_cardano_database_total_served_since_startup",
50        "Number of Cardano database artifact details served since startup on a Mithril aggregator node",
51        &[ORIGIN_TAG_LABEL]
52    ),
53    artifact_detail_mithril_stake_distribution_total_served_since_startup:MetricCounterWithLabels(
54        "mithril_aggregator_artifact_detail_mithril_stake_distribution_total_served_since_startup",
55        "Number of Mithril stake distribution artifact details served since startup on a Mithril aggregator node",
56        &[ORIGIN_TAG_LABEL]
57    ),
58    artifact_detail_cardano_stake_distribution_total_served_since_startup:MetricCounterWithLabels(
59        "mithril_aggregator_artifact_detail_cardano_stake_distribution_total_served_since_startup",
60        "Number of Cardano stake distribution artifact details served since startup on a Mithril aggregator node",
61        &[ORIGIN_TAG_LABEL]
62    ),
63    artifact_detail_cardano_transaction_total_served_since_startup:MetricCounterWithLabels(
64        "mithril_aggregator_artifact_detail_cardano_transaction_total_served_since_startup",
65        "Number of Cardano transaction artifact details served since startup on a Mithril aggregator node",
66        &[ORIGIN_TAG_LABEL]
67    ),
68    proof_cardano_transaction_total_proofs_served_since_startup:MetricCounterWithLabels(
69        "mithril_aggregator_proof_cardano_transaction_total_proofs_served_since_startup",
70        "Number of Cardano transaction proofs served since startup on a Mithril aggregator node",
71        &[ORIGIN_TAG_LABEL]
72    ),
73    proof_cardano_transaction_total_transactions_served_since_startup:MetricCounterWithLabels(
74        "mithril_aggregator_proof_cardano_transaction_total_transactions_served_since_startup",
75        "Number of Cardano transaction hashes requested for proof since startup on a Mithril aggregator node",
76        &[ORIGIN_TAG_LABEL]
77    ),
78    signer_registration_total_received_since_startup:MetricCounterWithLabels(
79        "mithril_aggregator_signer_registration_total_received_since_startup",
80        "Number of signer registrations received since startup on a Mithril aggregator node",
81        &[ORIGIN_TAG_LABEL]
82    ),
83    signature_registration_total_received_since_startup:MetricCounterWithLabels(
84        "mithril_aggregator_signature_registration_total_received_since_startup",
85        "Number of signature registrations received since startup on a Mithril aggregator node",
86        &[ORIGIN_TAG_LABEL]
87    ),
88    certificate_total_produced_since_startup:MetricCounter(
89        "mithril_aggregator_certificate_total_produced_since_startup",
90        "Number of certificates produced since startup on a Mithril aggregator node"
91    ),
92    artifact_cardano_immutable_files_full_total_produced_since_startup:MetricCounter(
93        "mithril_aggregator_artifact_cardano_db_total_produced_since_startup",
94        "Number of Cardano immutable files full artifacts produced since startup on a Mithril aggregator node"
95    ),
96    artifact_cardano_database_total_produced_since_startup:MetricCounter(
97        "mithril_aggregator_artifact_cardano_database_total_produced_since_startup",
98        "Number of Cardano database artifacts produced since startup on a Mithril aggregator node"
99    ),
100    artifact_mithril_stake_distribution_total_produced_since_startup:MetricCounter(
101        "mithril_aggregator_artifact_mithril_stake_distribution_total_produced_since_startup",
102        "Number of Mithril stake distribution artifacts produced since startup on a Mithril aggregator node"
103    ),
104    artifact_cardano_stake_distribution_total_produced_since_startup:MetricCounter(
105        "mithril_aggregator_artifact_cardano_stake_distribution_total_produced_since_startup",
106        "Number of Cardano stake distribution artifacts produced since startup on a Mithril aggregator node"
107    ),
108    artifact_cardano_transaction_total_produced_since_startup:MetricCounter(
109        "mithril_aggregator_artifact_cardano_transaction_total_produced_since_startup",
110        "Number of Cardano transaction artifacts produced since startup on a Mithril aggregator node"
111    ),
112    runtime_cycle_success_since_startup:MetricCounter(
113        "mithril_aggregator_runtime_cycle_success_since_startup",
114        "Number of successful runtime cycles since startup on a Mithril aggregator"
115    ),
116    runtime_cycle_total_since_startup:MetricCounter(
117        "mithril_aggregator_runtime_cycle_total_since_startup",
118        "Number of runtime cycles since startup on a Mithril aggregator"
119    )
120
121);
122
123impl MetricsService {
124    /// Export metrics in map.
125    pub fn export_metrics_map(&self) -> HashMap<String, HashMap<String, u32>> {
126        self.registry
127            .gather()
128            .iter()
129            .map(|metric_family| {
130                (
131                    metric_family.name().to_string(),
132                    self.build_metric_map_per_label(metric_family),
133                )
134            })
135            .collect()
136    }
137
138    fn build_label_key(&self, labels: &[LabelPair]) -> String {
139        labels
140            .iter()
141            .map(|p| p.value())
142            .collect::<Vec<_>>()
143            .join(",")
144    }
145
146    fn build_metric_map_per_label(&self, metric_family: &MetricFamily) -> HashMap<String, u32> {
147        metric_family
148            .get_metric()
149            .iter()
150            .map(|m| {
151                (
152                    self.build_label_key(m.get_label()),
153                    m.get_counter().as_ref().unwrap_or_default().value() as u32,
154                )
155            })
156            .collect()
157    }
158}
159
160#[cfg(test)]
161mod tests {
162    use crate::test_tools::TestLogger;
163
164    use super::*;
165
166    #[test]
167    fn should_export_counter_metrics_in_a_map() {
168        let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
169        let metric_a = metrics_service.get_runtime_cycle_total_since_startup();
170        let metric_b = metrics_service.get_certificate_total_produced_since_startup();
171        metric_a.increment_by(5);
172        metric_b.increment_by(12);
173
174        let export = metrics_service.export_metrics_map();
175        assert_eq!(5, export[&metric_a.name()][""]);
176        assert_eq!(12, export[&metric_b.name()][""]);
177    }
178
179    #[test]
180    fn should_export_counter_metrics_with_label_in_a_map() {
181        let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
182        let metric_a = metrics_service.get_certificate_detail_total_served_since_startup();
183        metric_a.increment_by(&["TOKEN_A"], 5);
184        metric_a.increment_by(&["TOKEN_B"], 12);
185
186        let export = metrics_service.export_metrics_map();
187        assert_eq!(5, export[&metric_a.name()]["TOKEN_A"]);
188        assert_eq!(12, export[&metric_a.name()]["TOKEN_B"]);
189    }
190
191    #[test]
192    fn should_export_several_times_and_counter_return_values_since_start() {
193        let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
194        let metric_a = metrics_service.get_runtime_cycle_total_since_startup();
195        metric_a.increment_by(5);
196
197        let export = metrics_service.export_metrics_map();
198        assert_eq!(5, export[&metric_a.name()][""]);
199
200        metric_a.increment();
201        let export = metrics_service.export_metrics_map();
202        assert_eq!(6, export[&metric_a.name()][""]);
203    }
204
205    #[test]
206    fn should_export_counter_even_the_value_is_0() {
207        let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
208        let metric_a = metrics_service.get_runtime_cycle_total_since_startup();
209
210        let export = metrics_service.export_metrics_map();
211        assert_eq!(0, export[&metric_a.name()][""]);
212    }
213
214    #[test]
215    fn metric_service_should_only_contain_counters_as_export_metrics_map_does_not_yet_support_other_types(
216    ) {
217        let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
218
219        for metric_family in metrics_service.registry.gather() {
220            for metric in metric_family.get_metric() {
221                assert!(metric.get_counter().is_some());
222            }
223        }
224    }
225}