sc_consensus/
metrics.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Metering tools for consensus
20
21use prometheus_endpoint::{
22	register, CounterVec, Histogram, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry,
23	U64,
24};
25
26use sp_runtime::traits::{Block as BlockT, NumberFor};
27
28use crate::import_queue::{BlockImportError, BlockImportStatus};
29
30/// Generic Prometheus metrics for common consensus functionality.
31#[derive(Clone)]
32pub(crate) struct Metrics {
33	pub import_queue_processed: CounterVec<U64>,
34	pub block_verification_time: HistogramVec,
35	pub block_verification_and_import_time: Histogram,
36	pub justification_import_time: Histogram,
37}
38
39impl Metrics {
40	pub(crate) fn register(registry: &Registry) -> Result<Self, PrometheusError> {
41		Ok(Self {
42			import_queue_processed: register(
43				CounterVec::new(
44					Opts::new(
45						"substrate_import_queue_processed_total",
46						"Blocks processed by import queue",
47					),
48					&["result"], // 'success or failure
49				)?,
50				registry,
51			)?,
52			block_verification_time: register(
53				HistogramVec::new(
54					HistogramOpts::new(
55						"substrate_block_verification_time",
56						"Time taken to verify blocks",
57					),
58					&["result"],
59				)?,
60				registry,
61			)?,
62			block_verification_and_import_time: register(
63				Histogram::with_opts(HistogramOpts::new(
64					"substrate_block_verification_and_import_time",
65					"Time taken to verify and import blocks",
66				))?,
67				registry,
68			)?,
69			justification_import_time: register(
70				Histogram::with_opts(HistogramOpts::new(
71					"substrate_justification_import_time",
72					"Time taken to import justifications",
73				))?,
74				registry,
75			)?,
76		})
77	}
78
79	pub fn report_import<B: BlockT>(
80		&self,
81		result: &Result<BlockImportStatus<NumberFor<B>>, BlockImportError>,
82	) {
83		let label = match result {
84			Ok(_) => "success",
85			Err(BlockImportError::IncompleteHeader(_)) => "incomplete_header",
86			Err(BlockImportError::VerificationFailed(_, _)) => "verification_failed",
87			Err(BlockImportError::BadBlock(_)) => "bad_block",
88			Err(BlockImportError::MissingState) => "missing_state",
89			Err(BlockImportError::UnknownParent) => "unknown_parent",
90			Err(BlockImportError::Cancelled) => "cancelled",
91			Err(BlockImportError::Other(_)) => "failed",
92		};
93
94		self.import_queue_processed.with_label_values(&[label]).inc();
95	}
96
97	pub fn report_verification(&self, success: bool, time: std::time::Duration) {
98		self.block_verification_time
99			.with_label_values(&[if success { "success" } else { "verification_failed" }])
100			.observe(time.as_secs_f64());
101	}
102
103	pub fn report_verification_and_import(&self, time: std::time::Duration) {
104		self.block_verification_and_import_time.observe(time.as_secs_f64());
105	}
106}