diff --git a/Cargo.lock b/Cargo.lock index f80f9e272bd0..8873755627ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4569,6 +4569,7 @@ dependencies = [ "sp-timestamp", "sp-transaction-pool", "sp-trie", + "substrate-prometheus-endpoint", "tokio 0.2.19", ] diff --git a/service/src/lib.rs b/service/src/lib.rs index 085dcdc78861..603c3de11447 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -367,6 +367,7 @@ macro_rules! new_full { validation_service_handle, slot_duration, backend, + service.prometheus_registry().as_ref(), ); let select_chain = service.select_chain().ok_or(ServiceError::SelectChainRequired)?; diff --git a/validation/Cargo.toml b/validation/Cargo.toml index 51e23155eab1..bca0a9d18588 100644 --- a/validation/Cargo.toml +++ b/validation/Cargo.toml @@ -34,6 +34,7 @@ bitvec = { version = "0.17.4", default-features = false, features = ["alloc"] } runtime_babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "master" } babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" } keystore = { package = "sc-keystore", git = "https://github.com/paritytech/substrate", branch = "master" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "master" } [dev-dependencies] sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/validation/src/block_production.rs b/validation/src/block_production.rs index e8d6c85925a2..a85b7b89bfd5 100644 --- a/validation/src/block_production.rs +++ b/validation/src/block_production.rs @@ -42,10 +42,14 @@ use inherents::InherentData; use sp_timestamp::TimestampInherentData; use log::{info, debug, warn, trace}; use sp_api::{ApiExt, ProvideRuntimeApi}; +use prometheus_endpoint::Registry as PrometheusRegistry; -use crate::validation_service::ServiceHandle; -use crate::dynamic_inclusion::DynamicInclusion; -use crate::Error; +use crate::{ + Error, + dynamic_inclusion::DynamicInclusion, + metrics::MetricsLink as PrometheusMetrics, + validation_service::ServiceHandle, +}; // block size limit. pub(crate) const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024; @@ -57,6 +61,7 @@ pub struct ProposerFactory { service_handle: ServiceHandle, babe_slot_duration: u64, backend: Arc, + metrics: PrometheusMetrics, } impl ProposerFactory { @@ -67,6 +72,7 @@ impl ProposerFactory { service_handle: ServiceHandle, babe_slot_duration: u64, backend: Arc, + prometheus: Option<&PrometheusRegistry>, ) -> Self { ProposerFactory { client, @@ -74,6 +80,7 @@ impl ProposerFactory { service_handle: service_handle, babe_slot_duration, backend, + metrics: PrometheusMetrics::new(prometheus), } } } @@ -109,6 +116,7 @@ where let transaction_pool = self.transaction_pool.clone(); let backend = self.backend.clone(); let slot_duration = self.babe_slot_duration.clone(); + let metrics = self.metrics.clone(); let maybe_proposer = self.service_handle .clone() @@ -120,6 +128,7 @@ where transaction_pool, slot_duration, backend, + metrics, }))); Box::pin(maybe_proposer) @@ -134,6 +143,7 @@ pub struct Proposer { transaction_pool: Arc, slot_duration: u64, backend: Arc, + metrics: PrometheusMetrics, } impl consensus::Proposer for Proposer where @@ -175,6 +185,7 @@ impl consensus::Proposer for Proposer consensus::Proposer for Proposer. + +//! Various validation metrics. + +use std::sync::Arc; + +use prometheus_endpoint::{register, PrometheusError, Registry, Histogram, HistogramOpts}; + +/// Optional shareable link to basic authorship metrics. +#[derive(Clone, Default)] +pub struct MetricsLink(Arc>); + +impl MetricsLink { + pub fn new(registry: Option<&Registry>) -> Self { + Self(Arc::new( + registry.and_then(|registry| + Metrics::register(registry) + .map_err(|err| { log::warn!("Failed to register prometheus metrics: {}", err); }) + .ok() + ) + )) + } + + pub fn report(&self, do_this: impl FnOnce(&Metrics)) { + if let Some(metrics) = self.0.as_ref() { + do_this(metrics); + } + } +} + +/// Authorship metrics. +pub struct Metrics { + pub block_constructed: Histogram, +} + +impl Metrics { + pub fn register(registry: &Registry) -> Result { + Ok(Self { + block_constructed: register( + Histogram::with_opts(HistogramOpts::new( + "polkadot_proposer_block_constructed", + "Histogram of time taken to construct new block", + ))?, + registry, + )?, + }) + } +}