1use 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#[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"], )?,
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}