diff --git a/node/collation-generation/src/lib.rs b/node/collation-generation/src/lib.rs index 8d6ed419e655..aee408637a99 100644 --- a/node/collation-generation/src/lib.rs +++ b/node/collation-generation/src/lib.rs @@ -27,7 +27,6 @@ use polkadot_node_subsystem::{ SubsystemError, SubsystemResult, SubsystemSender, }; use polkadot_node_subsystem_util::{ - metrics::{self, prometheus}, request_availability_cores, request_persisted_validation_data, request_validation_code, request_validation_code_hash, request_validators, }; @@ -44,6 +43,9 @@ mod error; #[cfg(test)] mod tests; +mod metrics; +use self::metrics::Metrics; + const LOG_TARGET: &'static str = "parachain::collation-generation"; /// Collation Generation Subsystem @@ -451,88 +453,3 @@ fn erasure_root( let chunks = polkadot_erasure_coding::obtain_chunks_v1(n_validators, &available_data)?; Ok(polkadot_erasure_coding::branches(&chunks).root()) } - -#[derive(Clone)] -struct MetricsInner { - collations_generated_total: prometheus::Counter, - new_activations_overall: prometheus::Histogram, - new_activations_per_relay_parent: prometheus::Histogram, - new_activations_per_availability_core: prometheus::Histogram, -} - -/// `CollationGenerationSubsystem` metrics. -#[derive(Default, Clone)] -pub struct Metrics(Option); - -impl Metrics { - fn on_collation_generated(&self) { - if let Some(metrics) = &self.0 { - metrics.collations_generated_total.inc(); - } - } - - /// Provide a timer for new activations which updates on drop. - fn time_new_activations(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.new_activations_overall.start_timer()) - } - - /// Provide a timer per relay parents which updates on drop. - fn time_new_activations_relay_parent( - &self, - ) -> Option { - self.0 - .as_ref() - .map(|metrics| metrics.new_activations_per_relay_parent.start_timer()) - } - - /// Provide a timer per availability core which updates on drop. - fn time_new_activations_availability_core( - &self, - ) -> Option { - self.0 - .as_ref() - .map(|metrics| metrics.new_activations_per_availability_core.start_timer()) - } -} - -impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> Result { - let metrics = MetricsInner { - collations_generated_total: prometheus::register( - prometheus::Counter::new( - "polkadot_parachain_collations_generated_total", - "Number of collations generated." - )?, - registry, - )?, - new_activations_overall: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "polkadot_parachain_collation_generation_new_activations", - "Time spent within fn handle_new_activations", - ) - )?, - registry, - )?, - new_activations_per_relay_parent: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "polkadot_parachain_collation_generation_per_relay_parent", - "Time spent handling a particular relay parent within fn handle_new_activations" - ) - )?, - registry, - )?, - new_activations_per_availability_core: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "polkadot_parachain_collation_generation_per_availability_core", - "Time spent handling a particular availability core for a relay parent in fn handle_new_activations", - ) - )?, - registry, - )?, - }; - Ok(Metrics(Some(metrics))) - } -} diff --git a/node/collation-generation/src/metrics.rs b/node/collation-generation/src/metrics.rs new file mode 100644 index 000000000000..008d8be0adcc --- /dev/null +++ b/node/collation-generation/src/metrics.rs @@ -0,0 +1,102 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) collations_generated_total: prometheus::Counter, + pub(crate) new_activations_overall: prometheus::Histogram, + pub(crate) new_activations_per_relay_parent: prometheus::Histogram, + pub(crate) new_activations_per_availability_core: prometheus::Histogram, +} + +/// `CollationGenerationSubsystem` metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_collation_generated(&self) { + if let Some(metrics) = &self.0 { + metrics.collations_generated_total.inc(); + } + } + + /// Provide a timer for new activations which updates on drop. + pub fn time_new_activations(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.new_activations_overall.start_timer()) + } + + /// Provide a timer per relay parents which updates on drop. + pub fn time_new_activations_relay_parent( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.new_activations_per_relay_parent.start_timer()) + } + + /// Provide a timer per availability core which updates on drop. + pub fn time_new_activations_availability_core( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.new_activations_per_availability_core.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + collations_generated_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_collations_generated_total", + "Number of collations generated." + )?, + registry, + )?, + new_activations_overall: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_new_activations", + "Time spent within fn handle_new_activations", + ) + )?, + registry, + )?, + new_activations_per_relay_parent: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_per_relay_parent", + "Time spent handling a particular relay parent within fn handle_new_activations" + ) + )?, + registry, + )?, + new_activations_per_availability_core: prometheus::register( + prometheus::Histogram::with_opts( + prometheus::HistogramOpts::new( + "polkadot_parachain_collation_generation_per_availability_core", + "Time spent handling a particular availability core for a relay parent in fn handle_new_activations", + ) + )?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/node/core/backing/src/lib.rs b/node/core/backing/src/lib.rs index f7212db27077..e26b99426b03 100644 --- a/node/core/backing/src/lib.rs +++ b/node/core/backing/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Polkadot. // Polkadot is free software: you can redistribute it and/or modify @@ -35,9 +35,7 @@ use polkadot_node_primitives::{ ValidationResult, BACKING_EXECUTION_TIMEOUT, }; use polkadot_node_subsystem_util::{ - self as util, - metrics::{self, prometheus}, - request_from_runtime, request_session_index_for_child, request_validator_groups, + self as util, request_from_runtime, request_session_index_for_child, request_validator_groups, request_validators, FromJobCommand, JobSender, Validator, }; use polkadot_primitives::v2::{ @@ -66,6 +64,9 @@ use statement_table::{ }; use thiserror::Error; +mod metrics; +use self::metrics::Metrics; + #[cfg(test)] mod tests; @@ -1303,93 +1304,6 @@ impl util::JobTrait for CandidateBackingJob { } } -#[derive(Clone)] -struct MetricsInner { - signed_statements_total: prometheus::Counter, - candidates_seconded_total: prometheus::Counter, - process_second: prometheus::Histogram, - process_statement: prometheus::Histogram, - get_backed_candidates: prometheus::Histogram, -} - -/// Candidate backing metrics. -#[derive(Default, Clone)] -pub struct Metrics(Option); - -impl Metrics { - fn on_statement_signed(&self) { - if let Some(metrics) = &self.0 { - metrics.signed_statements_total.inc(); - } - } - - fn on_candidate_seconded(&self) { - if let Some(metrics) = &self.0 { - metrics.candidates_seconded_total.inc(); - } - } - - /// Provide a timer for handling `CandidateBackingMessage:Second` which observes on drop. - fn time_process_second(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.process_second.start_timer()) - } - - /// Provide a timer for handling `CandidateBackingMessage::Statement` which observes on drop. - fn time_process_statement(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.process_statement.start_timer()) - } - - /// Provide a timer for handling `CandidateBackingMessage::GetBackedCandidates` which observes on drop. - fn time_get_backed_candidates( - &self, - ) -> Option { - self.0.as_ref().map(|metrics| metrics.get_backed_candidates.start_timer()) - } -} - -impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> Result { - let metrics = MetricsInner { - signed_statements_total: prometheus::register( - prometheus::Counter::new( - "polkadot_parachain_candidate_backing_signed_statements_total", - "Number of statements signed.", - )?, - registry, - )?, - candidates_seconded_total: prometheus::register( - prometheus::Counter::new( - "polkadot_parachain_candidate_backing_candidates_seconded_total", - "Number of candidates seconded.", - )?, - registry, - )?, - process_second: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_candidate_backing_process_second", - "Time spent within `candidate_backing::process_second`", - ))?, - registry, - )?, - process_statement: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_candidate_backing_process_statement", - "Time spent within `candidate_backing::process_statement`", - ))?, - registry, - )?, - get_backed_candidates: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_candidate_backing_get_backed_candidates", - "Time spent within `candidate_backing::get_backed_candidates`", - ))?, - registry, - )?, - }; - Ok(Metrics(Some(metrics))) - } -} - /// The candidate backing subsystem. pub type CandidateBackingSubsystem = polkadot_node_subsystem_util::JobSubsystem; diff --git a/node/core/backing/src/metrics.rs b/node/core/backing/src/metrics.rs new file mode 100644 index 000000000000..742d47a0acf2 --- /dev/null +++ b/node/core/backing/src/metrics.rs @@ -0,0 +1,106 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) signed_statements_total: prometheus::Counter, + pub(crate) candidates_seconded_total: prometheus::Counter, + pub(crate) process_second: prometheus::Histogram, + pub(crate) process_statement: prometheus::Histogram, + pub(crate) get_backed_candidates: prometheus::Histogram, +} + +/// Candidate backing metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_statement_signed(&self) { + if let Some(metrics) = &self.0 { + metrics.signed_statements_total.inc(); + } + } + + pub fn on_candidate_seconded(&self) { + if let Some(metrics) = &self.0 { + metrics.candidates_seconded_total.inc(); + } + } + + /// Provide a timer for handling `CandidateBackingMessage:Second` which observes on drop. + pub fn time_process_second(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.process_second.start_timer()) + } + + /// Provide a timer for handling `CandidateBackingMessage::Statement` which observes on drop. + pub fn time_process_statement( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.process_statement.start_timer()) + } + + /// Provide a timer for handling `CandidateBackingMessage::GetBackedCandidates` which observes on drop. + pub fn time_get_backed_candidates( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.get_backed_candidates.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + signed_statements_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_candidate_backing_signed_statements_total", + "Number of statements signed.", + )?, + registry, + )?, + candidates_seconded_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_candidate_backing_candidates_seconded_total", + "Number of candidates seconded.", + )?, + registry, + )?, + process_second: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_backing_process_second", + "Time spent within `candidate_backing::process_second`", + ))?, + registry, + )?, + process_statement: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_backing_process_statement", + "Time spent within `candidate_backing::process_statement`", + ))?, + registry, + )?, + get_backed_candidates: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_backing_get_backed_candidates", + "Time spent within `candidate_backing::get_backed_candidates`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/node/core/bitfield-signing/src/lib.rs b/node/core/bitfield-signing/src/lib.rs index 9e7ccd66c1c6..94b525ec6274 100644 --- a/node/core/bitfield-signing/src/lib.rs +++ b/node/core/bitfield-signing/src/lib.rs @@ -36,16 +36,15 @@ use polkadot_node_subsystem::{ }, ActivatedLeaf, LeafStatus, PerLeafSpan, SubsystemSender, }; -use polkadot_node_subsystem_util::{ - self as util, - metrics::{self, prometheus}, - JobSender, JobSubsystem, JobTrait, Validator, -}; +use polkadot_node_subsystem_util::{self as util, JobSender, JobSubsystem, JobTrait, Validator}; use polkadot_primitives::v2::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex}; use sp_keystore::{Error as KeystoreError, SyncCryptoStorePtr}; use std::{iter::FromIterator, pin::Pin, time::Duration}; use wasm_timer::{Delay, Instant}; +mod metrics; +use self::metrics::Metrics; + #[cfg(test)] mod tests; @@ -183,51 +182,6 @@ async fn construct_availability_bitfield( Ok(AvailabilityBitfield(core_bits)) } -#[derive(Clone)] -struct MetricsInner { - bitfields_signed_total: prometheus::Counter, - run: prometheus::Histogram, -} - -/// Bitfield signing metrics. -#[derive(Default, Clone)] -pub struct Metrics(Option); - -impl Metrics { - fn on_bitfield_signed(&self) { - if let Some(metrics) = &self.0 { - metrics.bitfields_signed_total.inc(); - } - } - - /// Provide a timer for `prune_povs` which observes on drop. - fn time_run(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.run.start_timer()) - } -} - -impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> Result { - let metrics = MetricsInner { - bitfields_signed_total: prometheus::register( - prometheus::Counter::new( - "polkadot_parachain_bitfields_signed_total", - "Number of bitfields signed.", - )?, - registry, - )?, - run: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_bitfield_signing_run", - "Time spent within `bitfield_signing::run`", - ))?, - registry, - )?, - }; - Ok(Metrics(Some(metrics))) - } -} - impl JobTrait for BitfieldSigningJob { type ToJob = BitfieldSigningMessage; type Error = Error; diff --git a/node/core/bitfield-signing/src/metrics.rs b/node/core/bitfield-signing/src/metrics.rs new file mode 100644 index 000000000000..ab4e73be0eeb --- /dev/null +++ b/node/core/bitfield-signing/src/metrics.rs @@ -0,0 +1,62 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) bitfields_signed_total: prometheus::Counter, + pub(crate) run: prometheus::Histogram, +} + +/// Bitfield signing metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_bitfield_signed(&self) { + if let Some(metrics) = &self.0 { + metrics.bitfields_signed_total.inc(); + } + } + + /// Provide a timer for `prune_povs` which observes on drop. + pub fn time_run(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.run.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + bitfields_signed_total: prometheus::register( + prometheus::Counter::new( + "polkadot_parachain_bitfields_signed_total", + "Number of bitfields signed.", + )?, + registry, + )?, + run: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_bitfield_signing_run", + "Time spent within `bitfield_signing::run`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/node/core/candidate-validation/src/lib.rs b/node/core/candidate-validation/src/lib.rs index 74e49990ba16..6da1bc0ac96c 100644 --- a/node/core/candidate-validation/src/lib.rs +++ b/node/core/candidate-validation/src/lib.rs @@ -38,7 +38,6 @@ use polkadot_node_subsystem::{ overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, SubsystemResult, SubsystemSender, }; -use polkadot_node_subsystem_util::metrics::{self, prometheus}; use polkadot_parachain::primitives::{ValidationParams, ValidationResult as WasmValidationResult}; use polkadot_primitives::v2::{ CandidateCommitments, CandidateDescriptor, CandidateReceipt, Hash, OccupiedCoreAssumption, @@ -53,6 +52,9 @@ use std::{path::PathBuf, sync::Arc, time::Duration}; use async_trait::async_trait; +mod metrics; +use self::metrics::Metrics; + #[cfg(test)] mod tests; @@ -685,95 +687,3 @@ fn perform_basic_checks( Ok(()) } - -#[derive(Clone)] -struct MetricsInner { - validation_requests: prometheus::CounterVec, - validate_from_chain_state: prometheus::Histogram, - validate_from_exhaustive: prometheus::Histogram, - validate_candidate_exhaustive: prometheus::Histogram, -} - -/// Candidate validation metrics. -#[derive(Default, Clone)] -pub struct Metrics(Option); - -impl Metrics { - fn on_validation_event(&self, event: &Result) { - if let Some(metrics) = &self.0 { - match event { - Ok(ValidationResult::Valid(_, _)) => { - metrics.validation_requests.with_label_values(&["valid"]).inc(); - }, - Ok(ValidationResult::Invalid(_)) => { - metrics.validation_requests.with_label_values(&["invalid"]).inc(); - }, - Err(_) => { - metrics.validation_requests.with_label_values(&["validation failure"]).inc(); - }, - } - } - } - - /// Provide a timer for `validate_from_chain_state` which observes on drop. - fn time_validate_from_chain_state( - &self, - ) -> Option { - self.0.as_ref().map(|metrics| metrics.validate_from_chain_state.start_timer()) - } - - /// Provide a timer for `validate_from_exhaustive` which observes on drop. - fn time_validate_from_exhaustive( - &self, - ) -> Option { - self.0.as_ref().map(|metrics| metrics.validate_from_exhaustive.start_timer()) - } - - /// Provide a timer for `validate_candidate_exhaustive` which observes on drop. - fn time_validate_candidate_exhaustive( - &self, - ) -> Option { - self.0 - .as_ref() - .map(|metrics| metrics.validate_candidate_exhaustive.start_timer()) - } -} - -impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> Result { - let metrics = MetricsInner { - validation_requests: prometheus::register( - prometheus::CounterVec::new( - prometheus::Opts::new( - "polkadot_parachain_validation_requests_total", - "Number of validation requests served.", - ), - &["validity"], - )?, - registry, - )?, - validate_from_chain_state: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_candidate_validation_validate_from_chain_state", - "Time spent within `candidate_validation::validate_from_chain_state`", - ))?, - registry, - )?, - validate_from_exhaustive: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_candidate_validation_validate_from_exhaustive", - "Time spent within `candidate_validation::validate_from_exhaustive`", - ))?, - registry, - )?, - validate_candidate_exhaustive: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_candidate_validation_validate_candidate_exhaustive", - "Time spent within `candidate_validation::validate_candidate_exhaustive`", - ))?, - registry, - )?, - }; - Ok(Metrics(Some(metrics))) - } -} diff --git a/node/core/candidate-validation/src/metrics.rs b/node/core/candidate-validation/src/metrics.rs new file mode 100644 index 000000000000..64112c6a387b --- /dev/null +++ b/node/core/candidate-validation/src/metrics.rs @@ -0,0 +1,110 @@ +// Copyright 2020-2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use super::{ValidationFailed, ValidationResult}; +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) validation_requests: prometheus::CounterVec, + pub(crate) validate_from_chain_state: prometheus::Histogram, + pub(crate) validate_from_exhaustive: prometheus::Histogram, + pub(crate) validate_candidate_exhaustive: prometheus::Histogram, +} + +/// Candidate validation metrics. +#[derive(Default, Clone)] +pub struct Metrics(Option); + +impl Metrics { + pub fn on_validation_event(&self, event: &Result) { + if let Some(metrics) = &self.0 { + match event { + Ok(ValidationResult::Valid(_, _)) => { + metrics.validation_requests.with_label_values(&["valid"]).inc(); + }, + Ok(ValidationResult::Invalid(_)) => { + metrics.validation_requests.with_label_values(&["invalid"]).inc(); + }, + Err(_) => { + metrics.validation_requests.with_label_values(&["validation failure"]).inc(); + }, + } + } + } + + /// Provide a timer for `validate_from_chain_state` which observes on drop. + pub fn time_validate_from_chain_state( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.validate_from_chain_state.start_timer()) + } + + /// Provide a timer for `validate_from_exhaustive` which observes on drop. + pub fn time_validate_from_exhaustive( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.validate_from_exhaustive.start_timer()) + } + + /// Provide a timer for `validate_candidate_exhaustive` which observes on drop. + pub fn time_validate_candidate_exhaustive( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.validate_candidate_exhaustive.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + validation_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_validation_requests_total", + "Number of validation requests served.", + ), + &["validity"], + )?, + registry, + )?, + validate_from_chain_state: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_validate_from_chain_state", + "Time spent within `candidate_validation::validate_from_chain_state`", + ))?, + registry, + )?, + validate_from_exhaustive: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_validate_from_exhaustive", + "Time spent within `candidate_validation::validate_from_exhaustive`", + ))?, + registry, + )?, + validate_candidate_exhaustive: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_candidate_validation_validate_candidate_exhaustive", + "Time spent within `candidate_validation::validate_candidate_exhaustive`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/node/core/chain-api/src/lib.rs b/node/core/chain-api/src/lib.rs index c7533021f6f8..bea0d513369a 100644 --- a/node/core/chain-api/src/lib.rs +++ b/node/core/chain-api/src/lib.rs @@ -37,13 +37,15 @@ use futures::prelude::*; use sc_client_api::AuxStore; use sp_blockchain::HeaderBackend; -use polkadot_node_subsystem_util::metrics::{self, prometheus}; use polkadot_primitives::v2::{Block, BlockId}; use polkadot_subsystem::{ messages::ChainApiMessage, overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, SubsystemResult, }; +mod metrics; +use self::metrics::Metrics; + #[cfg(test)] mod tests; @@ -163,122 +165,3 @@ where } } } - -#[derive(Clone)] -struct MetricsInner { - chain_api_requests: prometheus::CounterVec, - block_number: prometheus::Histogram, - block_header: prometheus::Histogram, - block_weight: prometheus::Histogram, - finalized_block_hash: prometheus::Histogram, - finalized_block_number: prometheus::Histogram, - ancestors: prometheus::Histogram, -} - -/// Chain API metrics. -#[derive(Default, Clone)] -pub struct Metrics(Option); - -impl Metrics { - fn on_request(&self, succeeded: bool) { - if let Some(metrics) = &self.0 { - if succeeded { - metrics.chain_api_requests.with_label_values(&["succeeded"]).inc(); - } else { - metrics.chain_api_requests.with_label_values(&["failed"]).inc(); - } - } - } - - /// Provide a timer for `block_number` which observes on drop. - fn time_block_number(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.block_number.start_timer()) - } - - /// Provide a timer for `block_header` which observes on drop. - fn time_block_header(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.block_header.start_timer()) - } - - /// Provide a timer for `block_weight` which observes on drop. - fn time_block_weight(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.block_weight.start_timer()) - } - - /// Provide a timer for `finalized_block_hash` which observes on drop. - fn time_finalized_block_hash(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.finalized_block_hash.start_timer()) - } - - /// Provide a timer for `finalized_block_number` which observes on drop. - fn time_finalized_block_number( - &self, - ) -> Option { - self.0.as_ref().map(|metrics| metrics.finalized_block_number.start_timer()) - } - - /// Provide a timer for `ancestors` which observes on drop. - fn time_ancestors(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.ancestors.start_timer()) - } -} - -impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> Result { - let metrics = MetricsInner { - chain_api_requests: prometheus::register( - prometheus::CounterVec::new( - prometheus::Opts::new( - "polkadot_parachain_chain_api_requests_total", - "Number of Chain API requests served.", - ), - &["success"], - )?, - registry, - )?, - block_number: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_chain_api_block_number", - "Time spent within `chain_api::block_number`", - ))?, - registry, - )?, - block_header: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_chain_api_block_headers", - "Time spent within `chain_api::block_headers`", - ))?, - registry, - )?, - block_weight: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_chain_api_block_weight", - "Time spent within `chain_api::block_weight`", - ))?, - registry, - )?, - finalized_block_hash: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_chain_api_finalized_block_hash", - "Time spent within `chain_api::finalized_block_hash`", - ))?, - registry, - )?, - finalized_block_number: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_chain_api_finalized_block_number", - "Time spent within `chain_api::finalized_block_number`", - ))?, - registry, - )?, - ancestors: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_chain_api_ancestors", - "Time spent within `chain_api::ancestors`", - ))?, - registry, - )?, - }; - Ok(Metrics(Some(metrics))) - } -} diff --git a/node/core/chain-api/src/metrics.rs b/node/core/chain-api/src/metrics.rs new file mode 100644 index 000000000000..23f455729e16 --- /dev/null +++ b/node/core/chain-api/src/metrics.rs @@ -0,0 +1,138 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) chain_api_requests: prometheus::CounterVec, + pub(crate) block_number: prometheus::Histogram, + pub(crate) block_header: prometheus::Histogram, + pub(crate) block_weight: prometheus::Histogram, + pub(crate) finalized_block_hash: prometheus::Histogram, + pub(crate) finalized_block_number: prometheus::Histogram, + pub(crate) ancestors: prometheus::Histogram, +} + +/// Chain API metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_request(&self, succeeded: bool) { + if let Some(metrics) = &self.0 { + if succeeded { + metrics.chain_api_requests.with_label_values(&["succeeded"]).inc(); + } else { + metrics.chain_api_requests.with_label_values(&["failed"]).inc(); + } + } + } + + /// Provide a timer for `block_number` which observes on drop. + pub fn time_block_number(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.block_number.start_timer()) + } + + /// Provide a timer for `block_header` which observes on drop. + pub fn time_block_header(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.block_header.start_timer()) + } + + /// Provide a timer for `block_weight` which observes on drop. + pub fn time_block_weight(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.block_weight.start_timer()) + } + + /// Provide a timer for `finalized_block_hash` which observes on drop. + pub fn time_finalized_block_hash( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.finalized_block_hash.start_timer()) + } + + /// Provide a timer for `finalized_block_number` which observes on drop. + pub fn time_finalized_block_number( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.finalized_block_number.start_timer()) + } + + /// Provide a timer for `ancestors` which observes on drop. + pub fn time_ancestors(&self) -> Option { + self.0.as_ref().map(|metrics| metrics.ancestors.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + chain_api_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_chain_api_requests_total", + "Number of Chain API requests served.", + ), + &["success"], + )?, + registry, + )?, + block_number: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_block_number", + "Time spent within `chain_api::block_number`", + ))?, + registry, + )?, + block_header: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_block_headers", + "Time spent within `chain_api::block_headers`", + ))?, + registry, + )?, + block_weight: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_block_weight", + "Time spent within `chain_api::block_weight`", + ))?, + registry, + )?, + finalized_block_hash: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_finalized_block_hash", + "Time spent within `chain_api::finalized_block_hash`", + ))?, + registry, + )?, + finalized_block_number: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_finalized_block_number", + "Time spent within `chain_api::finalized_block_number`", + ))?, + registry, + )?, + ancestors: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_chain_api_ancestors", + "Time spent within `chain_api::ancestors`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +} diff --git a/node/core/runtime-api/src/lib.rs b/node/core/runtime-api/src/lib.rs index 3665cb57ccbe..9f8377f0d713 100644 --- a/node/core/runtime-api/src/lib.rs +++ b/node/core/runtime-api/src/lib.rs @@ -22,7 +22,6 @@ #![deny(unused_crate_dependencies)] #![warn(missing_docs)] -use polkadot_node_subsystem_util::metrics::{self, prometheus}; use polkadot_primitives::{ runtime_api::ParachainHost, v2::{Block, BlockId, Hash}, @@ -45,6 +44,9 @@ use std::{collections::VecDeque, pin::Pin, sync::Arc}; mod cache; +mod metrics; +use self::metrics::Metrics; + #[cfg(test)] mod tests; @@ -526,63 +528,3 @@ where query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender), } } - -#[derive(Clone)] -struct MetricsInner { - chain_api_requests: prometheus::CounterVec, - make_runtime_api_request: prometheus::Histogram, -} - -/// Runtime API metrics. -#[derive(Default, Clone)] -pub struct Metrics(Option); - -impl Metrics { - fn on_request(&self, succeeded: bool) { - if let Some(metrics) = &self.0 { - if succeeded { - metrics.chain_api_requests.with_label_values(&["succeeded"]).inc(); - } else { - metrics.chain_api_requests.with_label_values(&["failed"]).inc(); - } - } - } - - fn on_cached_request(&self) { - self.0 - .as_ref() - .map(|metrics| metrics.chain_api_requests.with_label_values(&["cached"]).inc()); - } - - /// Provide a timer for `make_runtime_api_request` which observes on drop. - fn time_make_runtime_api_request( - &self, - ) -> Option { - self.0.as_ref().map(|metrics| metrics.make_runtime_api_request.start_timer()) - } -} - -impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> Result { - let metrics = MetricsInner { - chain_api_requests: prometheus::register( - prometheus::CounterVec::new( - prometheus::Opts::new( - "polkadot_parachain_runtime_api_requests_total", - "Number of Runtime API requests served.", - ), - &["success"], - )?, - registry, - )?, - make_runtime_api_request: prometheus::register( - prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( - "polkadot_parachain_runtime_api_make_runtime_api_request", - "Time spent within `runtime_api::make_runtime_api_request`", - ))?, - registry, - )?, - }; - Ok(Metrics(Some(metrics))) - } -} diff --git a/node/core/runtime-api/src/metrics.rs b/node/core/runtime-api/src/metrics.rs new file mode 100644 index 000000000000..c6affaf38914 --- /dev/null +++ b/node/core/runtime-api/src/metrics.rs @@ -0,0 +1,77 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use polkadot_node_subsystem_util::metrics::{self, prometheus}; + +#[derive(Clone)] +pub(crate) struct MetricsInner { + pub(crate) chain_api_requests: prometheus::CounterVec, + pub(crate) make_runtime_api_request: prometheus::Histogram, +} + +/// Runtime API metrics. +#[derive(Default, Clone)] +pub struct Metrics(pub(crate) Option); + +impl Metrics { + pub fn on_request(&self, succeeded: bool) { + if let Some(metrics) = &self.0 { + if succeeded { + metrics.chain_api_requests.with_label_values(&["succeeded"]).inc(); + } else { + metrics.chain_api_requests.with_label_values(&["failed"]).inc(); + } + } + } + + pub fn on_cached_request(&self) { + self.0 + .as_ref() + .map(|metrics| metrics.chain_api_requests.with_label_values(&["cached"]).inc()); + } + + /// Provide a timer for `make_runtime_api_request` which observes on drop. + pub fn time_make_runtime_api_request( + &self, + ) -> Option { + self.0.as_ref().map(|metrics| metrics.make_runtime_api_request.start_timer()) + } +} + +impl metrics::Metrics for Metrics { + fn try_register(registry: &prometheus::Registry) -> Result { + let metrics = MetricsInner { + chain_api_requests: prometheus::register( + prometheus::CounterVec::new( + prometheus::Opts::new( + "polkadot_parachain_runtime_api_requests_total", + "Number of Runtime API requests served.", + ), + &["success"], + )?, + registry, + )?, + make_runtime_api_request: prometheus::register( + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "polkadot_parachain_runtime_api_make_runtime_api_request", + "Time spent within `runtime_api::make_runtime_api_request`", + ))?, + registry, + )?, + }; + Ok(Metrics(Some(metrics))) + } +}