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