Skip to content

Commit

Permalink
feat: authorship custom metrics (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielMartinezRodriguez authored Jan 22, 2024
1 parent 7c52863 commit 83afbd5
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 14 deletions.
19 changes: 9 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ sc-service = { version = "0.10.0-dev", git = "https://github.com/paritytech/subs
sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
sc-proposer-metrics = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43"}
sc-offchain = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
sc-utils = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" }
# Substrate Primitive
Expand Down Expand Up @@ -206,6 +205,7 @@ pallet-evm-test-vector-support = { version = "1.0.0", git = "https://github.com/
pallet-hotfix-sufficients = { version = "1.0.0", git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.43", default-features = false }
# Stability Client
stbl-cli-authorship = { version = "1.0.0", path = './client/authorship' }
stbl-proposer-metrics = { version = "1.0.0", path = './client/proposer-metrics' }
# Stability
pallet-evm-precompile-blake2 = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.43", default-features = false }
pallet-evm-precompile-bn128 = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.43", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion client/authorship/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ log = { workspace = true }
prometheus-endpoint = { workspace = true }
sc-block-builder = { workspace = true }
sc-client-api = { workspace = true }
sc-proposer-metrics = { workspace = true }
stbl-proposer-metrics = { workspace = true }
fp-rpc = { workspace = true }
sc-telemetry = { workspace = true }
sc-transaction-pool-api = { workspace = true }
Expand Down
41 changes: 39 additions & 2 deletions client/authorship/src/authorship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use stbl_primitives_zero_gas_transactions_api::ZeroGasTransactionApi;
use std::{marker::PhantomData, pin::Pin, sync::Arc, time};

use prometheus_endpoint::Registry as PrometheusRegistry;
use sc_proposer_metrics::{EndProposingReason, MetricsLink as PrometheusMetrics};
use stbl_proposer_metrics::{EndProposingReason, MetricsLink as PrometheusMetrics};
use sp_core::crypto::KeyTypeId;
use sp_keystore::{Keystore, KeystorePtr};
use stbl_primitives_fee_compatible_api::CompatibleFeeApi;
Expand Down Expand Up @@ -456,6 +456,8 @@ where
let mut request = Box::pin(http_client.post(zero_gas_tx_pool).send().fuse());
let mut timeout = Box::pin(futures_timer::Delay::new(std::time::Duration::from_millis(self.zero_gas_tx_pool_timeout)).fuse());

let zgt_response_start = time::Instant::now();

let result_response_raw_zero = select! {
res = request => {
match res {
Expand All @@ -473,6 +475,16 @@ where
Err("Timeout fired waiting for get transaction from zero gas transaction pool")
},
};

let zgt_response_end = time::Instant::now();
self.metrics.report(|metrics| {
metrics.zgt_response_time.observe(
zgt_response_end
.saturating_duration_since(zgt_response_start)
.as_secs_f64(),
);
});


match result_response_raw_zero {
Ok(response) => {
Expand All @@ -493,13 +505,17 @@ where
None
};



// If we pull successfully from the zero gas transaction pool, we will try to push them to the block
if let Some(raw_zero_gas_transactions) = raw_zero_gas_transactions_option {
info!(
"📥 Fetched {:?} txns from zero-gas-transactions pool",
raw_zero_gas_transactions.transactions.len()
);

let zgt_inclusion_in_block_start = time::Instant::now();

if raw_zero_gas_transactions.transactions.len() > 0 {
let mut pending_raw_zero_gas_transactions = raw_zero_gas_transactions.transactions.iter();

Expand Down Expand Up @@ -619,6 +635,16 @@ where
}
};
}

let zgt_inclusion_in_block_end = time::Instant::now();

self.metrics.report(|metrics| {
metrics.zgt_inclusion_in_block_time.observe(
zgt_inclusion_in_block_end
.saturating_duration_since(zgt_inclusion_in_block_start)
.as_secs_f64(),
);
});
};

let mut unqueue_invalid = Vec::new();
Expand All @@ -643,6 +669,8 @@ where
debug!("Attempting to push transactions from the pool.");
debug!("Pool status: {:?}", self.transaction_pool.status());

let normal_extrinsic_inclusion_in_block_time_start = time::Instant::now();

let end_reason = loop {

let pending_tx = if let Some(pending_tx) = pending_iterator.next() {
Expand Down Expand Up @@ -741,7 +769,16 @@ where
}
};


let normal_extrinsic_inclusion_in_block_time_end = time::Instant::now();

self.metrics.report(|metrics| {
metrics.normal_extrinsic_inclusion_in_block_time.observe(
normal_extrinsic_inclusion_in_block_time_end
.saturating_duration_since(normal_extrinsic_inclusion_in_block_time_start)
.as_secs_f64(),
);
});

if matches!(end_reason, EndProposingReason::HitBlockSizeLimit) && !transaction_pushed {
warn!(
"Hit block size limit of `{}` without including any transaction!",
Expand Down
16 changes: 16 additions & 0 deletions client/proposer-metrics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "stbl-proposer-metrics"
version = "1.0.0"
authors = ["Stability Solutions"]
edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
repository = "https://github.com/stabilityprotocol/stability/"
description = "Basic metrics for block production."
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
log = { workspace = true }
prometheus-endpoint = { workspace = true, package = "substrate-prometheus-endpoint" }
3 changes: 3 additions & 0 deletions client/proposer-metrics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Prometheus stability basic proposer metrics.

License: GPL-3.0-or-later WITH Classpath-exception-2.0
143 changes: 143 additions & 0 deletions client/proposer-metrics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright 2023 Stability Solutions.
// This file is part of Stability.

// Stability 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.

// Stability 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 Stability. If not, see <http://www.gnu.org/licenses/>.


//! Prometheus basic proposer metrics.
use prometheus_endpoint::{
prometheus::CounterVec, register, Gauge, Histogram, HistogramOpts, Opts, PrometheusError,
Registry, U64,
};

/// Optional shareable link to basic authorship metrics.
#[derive(Clone, Default)]
pub struct MetricsLink(Option<Metrics>);

impl MetricsLink {
pub fn new(registry: Option<&Registry>) -> Self {
Self(registry.and_then(|registry| {
Metrics::register(registry)
.map_err(|err| {
log::warn!("Failed to register proposer prometheus metrics: {}", err)
})
.ok()
}))
}

pub fn report<O>(&self, do_this: impl FnOnce(&Metrics) -> O) -> Option<O> {
self.0.as_ref().map(do_this)
}
}

/// The reason why proposing a block ended.
pub enum EndProposingReason {
NoMoreTransactions,
HitDeadline,
HitBlockSizeLimit,
HitBlockWeightLimit,
}

/// Authorship metrics.
#[derive(Clone)]
pub struct Metrics {
pub block_constructed: Histogram,
pub number_of_transactions: Gauge<U64>,
pub end_proposing_reason: CounterVec,
pub create_inherents_time: Histogram,
pub create_block_proposal_time: Histogram,
pub zgt_response_time: Histogram,
pub zgt_inclusion_in_block_time: Histogram,
pub normal_extrinsic_inclusion_in_block_time: Histogram,

}

impl Metrics {
pub fn register(registry: &Registry) -> Result<Self, PrometheusError> {
Ok(Self {
block_constructed: register(
Histogram::with_opts(HistogramOpts::new(
"substrate_proposer_block_constructed",
"Histogram of time taken to construct new block",
))?,
registry,
)?,
number_of_transactions: register(
Gauge::new(
"substrate_proposer_number_of_transactions",
"Number of transactions included in block",
)?,
registry,
)?,
create_inherents_time: register(
Histogram::with_opts(HistogramOpts::new(
"substrate_proposer_create_inherents_time",
"Histogram of time taken to execute create inherents",
))?,
registry,
)?,
create_block_proposal_time: register(
Histogram::with_opts(HistogramOpts::new(
"substrate_proposer_block_proposal_time",
"Histogram of time taken to construct a block and prepare it for proposal",
))?,
registry,
)?,
end_proposing_reason: register(
CounterVec::new(
Opts::new(
"substrate_proposer_end_proposal_reason",
"The reason why the block proposing was ended. This doesn't include errors.",
),
&["reason"],
)?,
registry,
)?,
zgt_response_time: register(
Histogram::with_opts(HistogramOpts::new(
"stability_proposer_zgt_response_time",
"Histogram of time taken to get ZGT api response",
))?,
registry,
)?,
zgt_inclusion_in_block_time: register(
Histogram::with_opts(HistogramOpts::new(
"stability_proposer_zgt_inclusion_in_block_time",
"Histogram of time taken to include ZGT transactions in block",
))?,
registry,
)?,
normal_extrinsic_inclusion_in_block_time: register(
Histogram::with_opts(HistogramOpts::new(
"stability_proposer_normal_extrinsic_inclusion_in_block_time",
"Histogram of time taken to include normal extrinsics in block",
))?,
registry,
)?,
})
}

/// Report the reason why the proposing ended.
pub fn report_end_proposing_reason(&self, reason: EndProposingReason) {
let reason = match reason {
EndProposingReason::HitDeadline => "hit_deadline",
EndProposingReason::NoMoreTransactions => "no_more_transactions",
EndProposingReason::HitBlockSizeLimit => "hit_block_size_limit",
EndProposingReason::HitBlockWeightLimit => "hit_block_weight_limit",
};

self.end_proposing_reason.with_label_values(&[reason]).inc();
}
}

0 comments on commit 83afbd5

Please sign in to comment.