polkadot_availability_recovery/
metrics.rs1use polkadot_node_subsystem::prometheus::HistogramVec;
18use polkadot_node_subsystem_util::metrics::{
19 self,
20 prometheus::{
21 self, prometheus::HistogramTimer, Counter, CounterVec, Histogram, Opts, PrometheusError,
22 Registry, U64,
23 },
24};
25
26#[derive(Clone, Default)]
28pub struct Metrics(Option<MetricsInner>);
29
30#[derive(Clone)]
31struct MetricsInner {
32 chunk_requests_issued: CounterVec<U64>,
40
41 recovered_bytes_total: Counter<U64>,
45
46 chunk_requests_finished: CounterVec<U64>,
57
58 chunk_request_protocols: CounterVec<U64>,
60
61 full_data_requests_issued: Counter<U64>,
63
64 full_data_requests_finished: CounterVec<U64>,
74
75 time_chunk_request: HistogramVec,
79
80 time_erasure_recovery: HistogramVec,
84
85 time_erasure_reconstruct: HistogramVec,
90
91 time_reencode_chunks: Histogram,
94
95 time_full_recovery: Histogram,
98
99 full_recoveries_finished: CounterVec<U64>,
105
106 full_recoveries_started: Counter<U64>,
111}
112
113impl Metrics {
114 pub fn new_dummy() -> Self {
116 Metrics(None)
117 }
118
119 pub fn on_chunk_request_issued(&self, chunk_type: &str) {
121 if let Some(metrics) = &self.0 {
122 metrics.chunk_requests_issued.with_label_values(&[chunk_type]).inc()
123 }
124 }
125
126 pub fn on_full_request_issued(&self) {
128 if let Some(metrics) = &self.0 {
129 metrics.full_data_requests_issued.inc()
130 }
131 }
132
133 pub fn on_chunk_request_timeout(&self, chunk_type: &str) {
135 if let Some(metrics) = &self.0 {
136 metrics
137 .chunk_requests_finished
138 .with_label_values(&[chunk_type, "timeout"])
139 .inc()
140 }
141 }
142
143 pub fn on_full_request_timeout(&self) {
145 if let Some(metrics) = &self.0 {
146 metrics.full_data_requests_finished.with_label_values(&["timeout"]).inc()
147 }
148 }
149
150 pub fn on_chunk_request_no_such_chunk(&self, chunk_type: &str) {
152 if let Some(metrics) = &self.0 {
153 metrics
154 .chunk_requests_finished
155 .with_label_values(&[chunk_type, "no_such_chunk"])
156 .inc()
157 }
158 }
159
160 pub fn on_full_request_no_such_data(&self) {
162 if let Some(metrics) = &self.0 {
163 metrics.full_data_requests_finished.with_label_values(&["no_such_data"]).inc()
164 }
165 }
166
167 pub fn on_chunk_request_error(&self, chunk_type: &str) {
169 if let Some(metrics) = &self.0 {
170 metrics.chunk_requests_finished.with_label_values(&[chunk_type, "error"]).inc()
171 }
172 }
173
174 pub fn on_full_request_error(&self) {
176 if let Some(metrics) = &self.0 {
177 metrics.full_data_requests_finished.with_label_values(&["error"]).inc()
178 }
179 }
180
181 pub fn on_chunk_request_invalid(&self, chunk_type: &str) {
183 if let Some(metrics) = &self.0 {
184 metrics
185 .chunk_requests_finished
186 .with_label_values(&[chunk_type, "invalid"])
187 .inc()
188 }
189 }
190
191 pub fn on_full_request_invalid(&self) {
193 if let Some(metrics) = &self.0 {
194 metrics.full_data_requests_finished.with_label_values(&["invalid"]).inc()
195 }
196 }
197
198 pub fn on_chunk_request_succeeded(&self, chunk_type: &str) {
200 if let Some(metrics) = &self.0 {
201 metrics
202 .chunk_requests_finished
203 .with_label_values(&[chunk_type, "success"])
204 .inc()
205 }
206 }
207
208 pub fn on_chunk_response_v1(&self) {
210 if let Some(metrics) = &self.0 {
211 metrics.chunk_request_protocols.with_label_values(&["v1"]).inc()
212 }
213 }
214
215 pub fn on_chunk_response_v2(&self) {
217 if let Some(metrics) = &self.0 {
218 metrics.chunk_request_protocols.with_label_values(&["v2"]).inc()
219 }
220 }
221
222 pub fn on_full_request_succeeded(&self) {
224 if let Some(metrics) = &self.0 {
225 metrics.full_data_requests_finished.with_label_values(&["success"]).inc()
226 }
227 }
228
229 pub fn time_chunk_request(&self, chunk_type: &str) -> Option<HistogramTimer> {
231 self.0.as_ref().map(|metrics| {
232 metrics.time_chunk_request.with_label_values(&[chunk_type]).start_timer()
233 })
234 }
235
236 pub fn time_erasure_recovery(&self, chunk_type: &str) -> Option<HistogramTimer> {
238 self.0.as_ref().map(|metrics| {
239 metrics.time_erasure_recovery.with_label_values(&[chunk_type]).start_timer()
240 })
241 }
242
243 pub fn time_erasure_reconstruct(&self, chunk_type: &str) -> Option<HistogramTimer> {
245 self.0.as_ref().map(|metrics| {
246 metrics.time_erasure_reconstruct.with_label_values(&[chunk_type]).start_timer()
247 })
248 }
249
250 pub fn time_reencode_chunks(&self) -> Option<HistogramTimer> {
252 self.0.as_ref().map(|metrics| metrics.time_reencode_chunks.start_timer())
253 }
254
255 pub fn time_full_recovery(&self) -> Option<HistogramTimer> {
257 self.0.as_ref().map(|metrics| metrics.time_full_recovery.start_timer())
258 }
259
260 pub fn on_recovery_succeeded(&self, strategy_type: &str, bytes: usize) {
262 if let Some(metrics) = &self.0 {
263 metrics
264 .full_recoveries_finished
265 .with_label_values(&["success", strategy_type])
266 .inc();
267 metrics.recovered_bytes_total.inc_by(bytes as u64)
268 }
269 }
270
271 pub fn on_recovery_failed(&self, strategy_type: &str) {
273 if let Some(metrics) = &self.0 {
274 metrics
275 .full_recoveries_finished
276 .with_label_values(&["failure", strategy_type])
277 .inc()
278 }
279 }
280
281 pub fn on_recovery_invalid(&self, strategy_type: &str) {
283 if let Some(metrics) = &self.0 {
284 metrics
285 .full_recoveries_finished
286 .with_label_values(&["invalid", strategy_type])
287 .inc()
288 }
289 }
290
291 pub fn on_recovery_started(&self) {
293 if let Some(metrics) = &self.0 {
294 metrics.full_recoveries_started.inc()
295 }
296 }
297}
298
299impl metrics::Metrics for Metrics {
300 fn try_register(registry: &Registry) -> Result<Self, PrometheusError> {
301 let metrics = MetricsInner {
302 chunk_requests_issued: prometheus::register(
303 CounterVec::new(
304 Opts::new("polkadot_parachain_availability_recovery_chunk_requests_issued",
305 "Total number of issued chunk requests."),
306 &["type"]
307 )?,
308 registry,
309 )?,
310 full_data_requests_issued: prometheus::register(
311 Counter::new(
312 "polkadot_parachain_availability_recovery_full_data_requests_issued",
313 "Total number of issued full data requests.",
314 )?,
315 registry,
316 )?,
317 recovered_bytes_total: prometheus::register(
318 Counter::new(
319 "polkadot_parachain_availability_recovery_bytes_total",
320 "Total number of bytes recovered",
321 )?,
322 registry,
323 )?,
324 chunk_requests_finished: prometheus::register(
325 CounterVec::new(
326 Opts::new(
327 "polkadot_parachain_availability_recovery_chunk_requests_finished",
328 "Total number of chunk requests finished.",
329 ),
330 &["result", "type"],
331 )?,
332 registry,
333 )?,
334 chunk_request_protocols: prometheus::register(
335 CounterVec::new(
336 Opts::new(
337 "polkadot_parachain_availability_recovery_chunk_request_protocols",
338 "Total number of successful chunk requests, mapped by the protocol version (v1 or v2).",
339 ),
340 &["protocol"],
341 )?,
342 registry,
343 )?,
344 full_data_requests_finished: prometheus::register(
345 CounterVec::new(
346 Opts::new(
347 "polkadot_parachain_availability_recovery_full_data_requests_finished",
348 "Total number of full data requests finished.",
349 ),
350 &["result"],
351 )?,
352 registry,
353 )?,
354 time_chunk_request: prometheus::register(
355 prometheus::HistogramVec::new(prometheus::HistogramOpts::new(
356 "polkadot_parachain_availability_recovery_time_chunk_request",
357 "Time spent waiting for a response to a chunk request",
358 ), &["type"])?,
359 registry,
360 )?,
361 time_erasure_recovery: prometheus::register(
362 prometheus::HistogramVec::new(prometheus::HistogramOpts::new(
363 "polkadot_parachain_availability_recovery_time_erasure_recovery",
364 "Time spent to recover the erasure code and verify the merkle root by re-encoding as erasure chunks",
365 ), &["type"])?,
366 registry,
367 )?,
368 time_erasure_reconstruct: prometheus::register(
369 prometheus::HistogramVec::new(prometheus::HistogramOpts::new(
370 "polkadot_parachain_availability_recovery_time_erasure_reconstruct",
371 "Time spent to reconstruct the data from chunks",
372 ), &["type"])?,
373 registry,
374 )?,
375 time_reencode_chunks: prometheus::register(
376 prometheus::Histogram::with_opts(prometheus::HistogramOpts::new(
377 "polkadot_parachain_availability_reencode_chunks",
378 "Time spent re-encoding the data as erasure chunks",
379 ))?,
380 registry,
381 )?,
382 time_full_recovery: prometheus::register(
383 prometheus::Histogram::with_opts(prometheus::HistogramOpts::new(
384 "polkadot_parachain_availability_recovery_time_total",
385 "Time a full recovery process took, either until failure or successful erasure decoding.",
386 ))?,
387 registry,
388 )?,
389 full_recoveries_finished: prometheus::register(
390 CounterVec::new(
391 Opts::new(
392 "polkadot_parachain_availability_recovery_recoveries_finished",
393 "Total number of recoveries that finished.",
394 ),
395 &["result", "strategy_type"],
396 )?,
397 registry,
398 )?,
399 full_recoveries_started: prometheus::register(
400 Counter::new(
401 "polkadot_parachain_availability_recovery_recoveries_started",
402 "Total number of started recoveries.",
403 )?,
404 registry,
405 )?,
406 };
407 Ok(Metrics(Some(metrics)))
408 }
409}