polkadot_approval_distribution/
metrics.rs1use polkadot_node_metrics::metrics::{prometheus, Metrics as MetricsTrait};
18use polkadot_node_primitives::approval::v2::AssignmentCertKindV2;
19
20#[derive(Default, Clone)]
22pub struct Metrics(Option<MetricsInner>);
23
24#[derive(Clone)]
25struct MetricsInner {
26 assignments_imported_total: prometheus::CounterVec<prometheus::U64>,
27 approvals_imported_total: prometheus::Counter<prometheus::U64>,
28 unified_with_peer_total: prometheus::Counter<prometheus::U64>,
29 aggression_l1_messages_total: prometheus::Counter<prometheus::U64>,
30 aggression_l2_messages_total: prometheus::Counter<prometheus::U64>,
31 time_unify_with_peer: prometheus::Histogram,
32 time_import_pending_now_known: prometheus::Histogram,
33 assignments_received_result: prometheus::CounterVec<prometheus::U64>,
34 approvals_received_result: prometheus::CounterVec<prometheus::U64>,
35}
36
37trait AsLabel {
38 fn as_label(&self) -> &str;
39}
40
41impl AsLabel for &AssignmentCertKindV2 {
42 fn as_label(&self) -> &str {
43 match self {
44 AssignmentCertKindV2::RelayVRFDelay { .. } => "VRF Delay",
45 AssignmentCertKindV2::RelayVRFModulo { .. } => "VRF Modulo",
46 AssignmentCertKindV2::RelayVRFModuloCompact { .. } => "VRF Modulo Compact",
47 }
48 }
49}
50
51impl Metrics {
52 pub(crate) fn on_assignment_imported(&self, kind: &AssignmentCertKindV2) {
53 if let Some(metrics) = &self.0 {
54 metrics.assignments_imported_total.with_label_values(&[kind.as_label()]).inc();
55 }
56 }
57
58 pub(crate) fn on_approval_imported(&self) {
59 if let Some(metrics) = &self.0 {
60 metrics.approvals_imported_total.inc();
61 }
62 }
63
64 pub(crate) fn on_unify_with_peer(&self) {
65 if let Some(metrics) = &self.0 {
66 metrics.unified_with_peer_total.inc();
67 }
68 }
69
70 pub(crate) fn time_unify_with_peer(&self) -> Option<prometheus::prometheus::HistogramTimer> {
71 self.0.as_ref().map(|metrics| metrics.time_unify_with_peer.start_timer())
72 }
73
74 pub(crate) fn time_import_pending_now_known(
75 &self,
76 ) -> Option<prometheus::prometheus::HistogramTimer> {
77 self.0
78 .as_ref()
79 .map(|metrics| metrics.time_import_pending_now_known.start_timer())
80 }
81
82 pub(crate) fn on_approval_recent_outdated(&self) {
83 if let Some(metrics) = &self.0 {
84 metrics.approvals_received_result.with_label_values(&["outdated"]).inc()
85 }
86 }
87
88 pub(crate) fn on_approval_invalid_block(&self) {
89 if let Some(metrics) = &self.0 {
90 metrics.approvals_received_result.with_label_values(&["invalidblock"]).inc()
91 }
92 }
93
94 pub(crate) fn on_approval_unknown_assignment(&self) {
95 if let Some(metrics) = &self.0 {
96 metrics
97 .approvals_received_result
98 .with_label_values(&["unknownassignment"])
99 .inc()
100 }
101 }
102
103 pub(crate) fn on_approval_duplicate(&self) {
104 if let Some(metrics) = &self.0 {
105 metrics.approvals_received_result.with_label_values(&["duplicate"]).inc()
106 }
107 }
108
109 pub(crate) fn on_approval_out_of_view(&self) {
110 if let Some(metrics) = &self.0 {
111 metrics.approvals_received_result.with_label_values(&["outofview"]).inc()
112 }
113 }
114
115 pub(crate) fn on_approval_good_known(&self) {
116 if let Some(metrics) = &self.0 {
117 metrics.approvals_received_result.with_label_values(&["goodknown"]).inc()
118 }
119 }
120
121 pub(crate) fn on_approval_bad(&self) {
122 if let Some(metrics) = &self.0 {
123 metrics.approvals_received_result.with_label_values(&["bad"]).inc()
124 }
125 }
126
127 pub(crate) fn on_approval_bug(&self) {
128 if let Some(metrics) = &self.0 {
129 metrics.approvals_received_result.with_label_values(&["bug"]).inc()
130 }
131 }
132
133 pub(crate) fn on_assignment_recent_outdated(&self) {
134 if let Some(metrics) = &self.0 {
135 metrics.assignments_received_result.with_label_values(&["outdated"]).inc()
136 }
137 }
138
139 pub(crate) fn on_assignment_invalid_block(&self) {
140 if let Some(metrics) = &self.0 {
141 metrics.assignments_received_result.with_label_values(&["invalidblock"]).inc()
142 }
143 }
144
145 pub(crate) fn on_assignment_duplicate(&self) {
146 if let Some(metrics) = &self.0 {
147 metrics.assignments_received_result.with_label_values(&["duplicate"]).inc()
148 }
149 }
150
151 pub(crate) fn on_assignment_out_of_view(&self) {
152 if let Some(metrics) = &self.0 {
153 metrics.assignments_received_result.with_label_values(&["outofview"]).inc()
154 }
155 }
156
157 pub(crate) fn on_assignment_good_known(&self) {
158 if let Some(metrics) = &self.0 {
159 metrics.assignments_received_result.with_label_values(&["goodknown"]).inc()
160 }
161 }
162
163 pub(crate) fn on_assignment_bad(&self) {
164 if let Some(metrics) = &self.0 {
165 metrics.assignments_received_result.with_label_values(&["bad"]).inc()
166 }
167 }
168
169 pub(crate) fn on_assignment_far(&self) {
170 if let Some(metrics) = &self.0 {
171 metrics.assignments_received_result.with_label_values(&["far"]).inc()
172 }
173 }
174
175 pub(crate) fn on_aggression_l1(&self) {
176 if let Some(metrics) = &self.0 {
177 metrics.aggression_l1_messages_total.inc();
178 }
179 }
180
181 pub(crate) fn on_aggression_l2(&self) {
182 if let Some(metrics) = &self.0 {
183 metrics.aggression_l2_messages_total.inc();
184 }
185 }
186}
187
188impl MetricsTrait for Metrics {
189 fn try_register(registry: &prometheus::Registry) -> Result<Self, prometheus::PrometheusError> {
190 let metrics = MetricsInner {
191 assignments_imported_total: prometheus::register(
192 prometheus::CounterVec::new(
193 prometheus::Opts::new(
194 "polkadot_parachain_assignments_imported_total",
195 "Number of valid assignments imported locally or from other peers.",
196 ),
197 &["kind"],
198 )?,
199 registry,
200 )?,
201 approvals_imported_total: prometheus::register(
202 prometheus::Counter::new(
203 "polkadot_parachain_approvals_imported_total",
204 "Number of valid approvals imported locally or from other peers.",
205 )?,
206 registry,
207 )?,
208 unified_with_peer_total: prometheus::register(
209 prometheus::Counter::new(
210 "polkadot_parachain_unified_with_peer_total",
211 "Number of times `unify_with_peer` is called.",
212 )?,
213 registry,
214 )?,
215 aggression_l1_messages_total: prometheus::register(
216 prometheus::Counter::new(
217 "polkadot_parachain_approval_distribution_aggression_l1_messages_total",
218 "Number of messages in approval distribution for which aggression L1 has been triggered",
219 )?,
220 registry,
221 )?,
222 aggression_l2_messages_total: prometheus::register(
223 prometheus::Counter::new(
224 "polkadot_parachain_approval_distribution_aggression_l2_messages_total",
225 "Number of messages in approval distribution for which aggression L2 has been triggered",
226 )?,
227 registry,
228 )?,
229 time_unify_with_peer: prometheus::register(
230 prometheus::Histogram::with_opts(
231 prometheus::HistogramOpts::new(
232 "polkadot_parachain_time_unify_with_peer",
233 "Time spent within fn `unify_with_peer`.",
234 )
235 .buckets(vec![
236 0.000625, 0.00125, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.1, 0.25,
237 0.5, 1.0, 2.5, 5.0, 10.0,
238 ]),
239 )?,
240 registry,
241 )?,
242 time_import_pending_now_known: prometheus::register(
243 prometheus::Histogram::with_opts(prometheus::HistogramOpts::new(
244 "polkadot_parachain_time_import_pending_now_known",
245 "Time spent on importing pending assignments and approvals.",
246 ).buckets(vec![0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768, 4.9152, 6.5536,]))?,
247 registry,
248 )?,
249 assignments_received_result: prometheus::register(
250 prometheus::CounterVec::new(
251 prometheus::Opts::new(
252 "polkadot_parachain_assignments_received_result",
253 "Result of a processed assignment",
254 ),
255 &["status"]
256 )?,
257 registry,
258 )?,
259 approvals_received_result: prometheus::register(
260 prometheus::CounterVec::new(
261 prometheus::Opts::new(
262 "polkadot_parachain_approvals_received_result",
263 "Result of a processed approval",
264 ),
265 &["status"]
266 )?,
267 registry,
268 )?,
269 };
270 Ok(Metrics(Some(metrics)))
271 }
272}