mithril_aggregator/metrics/
service.rs1use std::collections::HashMap;
2
3use mithril_metric::{MetricCounterWithLabels, MetricsServiceExporter, build_metrics_service};
4
5use mithril_metric::metric::{MetricCollector, MetricCounter};
6use prometheus::proto::{LabelPair, Metric, MetricFamily};
7
8static CLIENT_ORIGIN_TAG_LABEL: &str = "origin_tag";
10static SIGNER_REGISTRATION_ORIGIN_TAG_LABEL: &str = "origin_tag";
11static SIGNER_SIGNATURE_ORIGIN_TAG_LABEL: &str = "origin_tag";
12static CLIENT_TYPE_LABEL: &str = "client_type";
13
14build_metrics_service!(
15 MetricsService,
16
17 certificate_detail_total_served_since_startup:MetricCounterWithLabels(
18 "certificate_detail_total_served_since_startup",
19 "Number of certificate details served since startup on a Mithril aggregator node",
20 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
21 ),
22 artifact_detail_cardano_immutable_files_full_total_served_since_startup:MetricCounterWithLabels(
23 "mithril_aggregator_artifact_detail_cardano_db_total_served_since_startup",
24 "Number of Cardano immutable files full artifact details served since startup on a Mithril aggregator node",
25 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
26 ),
27 cardano_immutable_files_full_total_restoration_since_startup:MetricCounterWithLabels(
28 "mithril_aggregator_cardano_db_total_restoration_since_startup",
29 "Number of Cardano immutable files full restorations since startup on a Mithril aggregator node",
30 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
31 ),
32 cardano_database_immutable_files_restored_since_startup:MetricCounterWithLabels(
33 "mithril_aggregator_cardano_db_immutable_files_restored_since_startup",
34 "Number of Cardano immutable files restored since startup on a Mithril aggregator node",
35 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
36 ),
37 cardano_database_ancillary_files_restored_since_startup:MetricCounterWithLabels(
38 "mithril_aggregator_cardano_db_ancillary_files_restored_since_startup",
39 "Number of Cardano ancillary files restored since startup on a Mithril aggregator node",
40 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
41 ),
42 cardano_database_complete_restoration_since_startup:MetricCounterWithLabels(
43 "mithril_aggregator_cardano_db_complete_restoration_since_startup",
44 "Number of complete Cardano database restoration since startup on a Mithril aggregator node",
45 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
46 ),
47 cardano_database_partial_restoration_since_startup:MetricCounterWithLabels(
48 "mithril_aggregator_cardano_db_partial_restoration_since_startup",
49 "Number of partial Cardano database restoration since startup on a Mithril aggregator node",
50 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
51 ),
52 artifact_detail_cardano_database_total_served_since_startup:MetricCounterWithLabels(
53 "mithril_aggregator_artifact_detail_cardano_database_total_served_since_startup",
54 "Number of Cardano database artifact details served since startup on a Mithril aggregator node",
55 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
56 ),
57 artifact_detail_mithril_stake_distribution_total_served_since_startup:MetricCounterWithLabels(
58 "mithril_aggregator_artifact_detail_mithril_stake_distribution_total_served_since_startup",
59 "Number of Mithril stake distribution artifact details served since startup on a Mithril aggregator node",
60 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
61 ),
62 artifact_detail_cardano_stake_distribution_total_served_since_startup:MetricCounterWithLabels(
63 "mithril_aggregator_artifact_detail_cardano_stake_distribution_total_served_since_startup",
64 "Number of Cardano stake distribution artifact details served since startup on a Mithril aggregator node",
65 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
66 ),
67 artifact_detail_cardano_transaction_total_served_since_startup:MetricCounterWithLabels(
68 "mithril_aggregator_artifact_detail_cardano_transaction_total_served_since_startup",
69 "Number of Cardano transaction artifact details served since startup on a Mithril aggregator node",
70 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
71 ),
72 artifact_detail_cardano_blocks_transactions_total_served_since_startup:MetricCounterWithLabels(
73 "mithril_aggregator_artifact_detail_cardano_blocks_transactions_total_served_since_startup",
74 "Number of Cardano blocks transactions artifact details served since startup on a Mithril aggregator node",
75 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
76 ),
77 proof_cardano_transaction_total_proofs_served_since_startup:MetricCounterWithLabels(
78 "mithril_aggregator_proof_cardano_transaction_total_proofs_served_since_startup",
79 "Number of Cardano transaction proofs served since startup on a Mithril aggregator node",
80 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
81 ),
82 proof_cardano_transaction_total_transactions_served_since_startup:MetricCounterWithLabels(
83 "mithril_aggregator_proof_cardano_transaction_total_transactions_served_since_startup",
84 "Number of Cardano transaction hashes requested for proof since startup on a Mithril aggregator node",
85 &[CLIENT_ORIGIN_TAG_LABEL, CLIENT_TYPE_LABEL]
86 ),
87 signer_registration_total_received_since_startup:MetricCounterWithLabels(
88 "mithril_aggregator_signer_registration_total_received_since_startup",
89 "Number of signer registrations received since startup on a Mithril aggregator node",
90 &[SIGNER_REGISTRATION_ORIGIN_TAG_LABEL]
91 ),
92 signer_registration_total_successful_since_startup:MetricCounterWithLabels(
93 "mithril_aggregator_signer_registration_total_successful_since_startup",
94 "Number of successful signer registrations received since startup on a Mithril aggregator node",
95 &[SIGNER_REGISTRATION_ORIGIN_TAG_LABEL]
96 ),
97 signature_registration_total_received_since_startup:MetricCounterWithLabels(
98 "mithril_aggregator_signature_registration_total_received_since_startup",
99 "Number of signature registrations received since startup on a Mithril aggregator node",
100 &[SIGNER_SIGNATURE_ORIGIN_TAG_LABEL]
101 ),
102 signature_registration_total_successful_since_startup:MetricCounterWithLabels(
103 "mithril_aggregator_signature_registration_total_successful_since_startup",
104 "Number of successful signature registrations received since startup on a Mithril aggregator node",
105 &[SIGNER_SIGNATURE_ORIGIN_TAG_LABEL]
106 ),
107 certificate_total_produced_since_startup:MetricCounter(
108 "mithril_aggregator_certificate_total_produced_since_startup",
109 "Number of certificates produced since startup on a Mithril aggregator node"
110 ),
111 artifact_cardano_immutable_files_full_total_produced_since_startup:MetricCounter(
112 "mithril_aggregator_artifact_cardano_db_total_produced_since_startup",
113 "Number of Cardano immutable files full artifacts produced since startup on a Mithril aggregator node"
114 ),
115 artifact_cardano_database_total_produced_since_startup:MetricCounter(
116 "mithril_aggregator_artifact_cardano_database_total_produced_since_startup",
117 "Number of Cardano database artifacts produced since startup on a Mithril aggregator node"
118 ),
119 artifact_mithril_stake_distribution_total_produced_since_startup:MetricCounter(
120 "mithril_aggregator_artifact_mithril_stake_distribution_total_produced_since_startup",
121 "Number of Mithril stake distribution artifacts produced since startup on a Mithril aggregator node"
122 ),
123 artifact_cardano_stake_distribution_total_produced_since_startup:MetricCounter(
124 "mithril_aggregator_artifact_cardano_stake_distribution_total_produced_since_startup",
125 "Number of Cardano stake distribution artifacts produced since startup on a Mithril aggregator node"
126 ),
127 artifact_cardano_transaction_total_produced_since_startup:MetricCounter(
128 "mithril_aggregator_artifact_cardano_transaction_total_produced_since_startup",
129 "Number of Cardano transaction artifacts produced since startup on a Mithril aggregator node"
130 ),
131 artifact_cardano_blocks_transactions_total_produced_since_startup:MetricCounter(
132 "mithril_aggregator_artifact_cardano_blocks_transactions_total_produced_since_startup",
133 "Number of Cardano blocks transactions artifacts produced since startup on a Mithril aggregator node"
134 ),
135 runtime_cycle_success_since_startup:MetricCounter(
136 "mithril_aggregator_runtime_cycle_success_since_startup",
137 "Number of successful runtime cycles since startup on a Mithril aggregator"
138 ),
139 runtime_cycle_total_since_startup:MetricCounter(
140 "mithril_aggregator_runtime_cycle_total_since_startup",
141 "Number of runtime cycles since startup on a Mithril aggregator"
142 )
143
144);
145
146impl MetricsService {
147 pub fn export_metrics_map(&self) -> HashMap<String, HashMap<String, MetricLabelValueMap>> {
149 self.registry
150 .gather()
151 .iter()
152 .map(|metric_family| {
153 (
154 metric_family.name().to_string(),
155 self.build_metric_map(metric_family),
156 )
157 })
158 .collect()
159 }
160
161 fn build_label_key(&self, labels: &[LabelPair]) -> String {
162 labels.iter().map(|p| p.value()).collect::<Vec<_>>().join(",")
163 }
164
165 fn build_metric_map(
166 &self,
167 metric_family: &MetricFamily,
168 ) -> HashMap<String, MetricLabelValueMap> {
169 metric_family
170 .get_metric()
171 .iter()
172 .map(|m| {
173 (
174 self.build_label_key(m.get_label()),
175 MetricLabelValueMap::new(m.clone()),
176 )
177 })
178 .collect()
179 }
180}
181
182type LabelName = String;
183type LabelValue = String;
184
185#[derive(Debug, Clone, PartialEq, Eq)]
186pub struct MetricLabelValueMap {
188 pub label_value_map: HashMap<LabelName, LabelValue>,
190 pub counter: i32,
192}
193
194impl MetricLabelValueMap {
195 pub fn new(metric: Metric) -> Self {
197 Self {
198 label_value_map: metric
199 .get_label()
200 .iter()
201 .map(|label| (label.name().to_string(), label.value().to_string()))
202 .collect(),
203 counter: metric.get_counter().as_ref().unwrap_or_default().value() as i32,
204 }
205 }
206}
207
208impl Default for MetricLabelValueMap {
209 fn default() -> Self {
211 Self {
212 label_value_map: HashMap::new(),
213 counter: 0,
214 }
215 }
216}
217
218#[cfg(test)]
219mod tests {
220 use crate::test::TestLogger;
221
222 use super::*;
223
224 #[test]
225 fn should_export_counter_metrics_in_a_map() {
226 let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
227 let metric_a = metrics_service.get_runtime_cycle_total_since_startup();
228 let metric_b = metrics_service.get_certificate_total_produced_since_startup();
229 metric_a.increment_by(5);
230 metric_b.increment_by(12);
231
232 let export = metrics_service.export_metrics_map();
233 assert_eq!(5, export[&metric_a.name()][""].counter);
234 assert_eq!(12, export[&metric_b.name()][""].counter);
235 }
236
237 #[test]
238 fn should_export_counter_metrics_with_label_in_a_map() {
239 let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
240 let metric_a = metrics_service.get_certificate_detail_total_served_since_startup();
241 metric_a.increment_by(&["A", "B"], 5);
242 metric_a.increment_by(&["1", "2"], 12);
243
244 let export = metrics_service.export_metrics_map();
245
246 let metric_a_token_a_b = export[&metric_a.name()]["B,A"].clone();
247 let metric_a_token_1_2 = export[&metric_a.name()]["2,1"].clone();
248
249 assert_eq!(5, metric_a_token_a_b.to_owned().counter);
250 assert_eq!(
251 "A",
252 metric_a_token_a_b.to_owned().label_value_map["origin_tag"]
253 );
254 assert_eq!(
255 "B",
256 metric_a_token_a_b.to_owned().label_value_map["client_type"]
257 );
258
259 assert_eq!(12, metric_a_token_1_2.to_owned().counter);
260 assert_eq!(
261 "1",
262 metric_a_token_1_2.to_owned().label_value_map["origin_tag"]
263 );
264 assert_eq!(
265 "2",
266 metric_a_token_1_2.to_owned().label_value_map["client_type"]
267 );
268 }
269
270 #[test]
271 fn should_export_several_times_and_counter_return_values_since_start() {
272 let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
273 let metric_a = metrics_service.get_runtime_cycle_total_since_startup();
274 metric_a.increment_by(5);
275
276 let export = metrics_service.export_metrics_map();
277 assert_eq!(5, export[&metric_a.name()][""].counter);
278
279 metric_a.increment();
280 let export = metrics_service.export_metrics_map();
281 assert_eq!(6, export[&metric_a.name()][""].counter);
282 }
283
284 #[test]
285 fn should_export_counter_even_the_value_is_0() {
286 let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
287 let metric_a = metrics_service.get_runtime_cycle_total_since_startup();
288
289 let export = metrics_service.export_metrics_map();
290 assert_eq!(0, export[&metric_a.name()][""].counter);
291 }
292
293 #[test]
294 fn metric_service_should_only_contain_counters_as_export_metrics_map_does_not_yet_support_other_types()
295 {
296 let metrics_service = MetricsService::new(TestLogger::stdout()).unwrap();
297
298 for metric_family in metrics_service.registry.gather() {
299 for metric in metric_family.get_metric() {
300 assert!(metric.get_counter().is_some());
301 }
302 }
303 }
304}