Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: authorship custom metrics #164

Merged
merged 2 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
}
}
Loading