mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-08-05 12:33:15 +00:00
refactor(metrics): move metrics into a separate crates and reuse names in dashboard generation
This commit is contained in:
parent
462de8f11d
commit
ea36fa2e93
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -2297,6 +2297,8 @@ name = "dashboard_gen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"json-pretty-compact",
|
||||
"sequencer_core_metrics",
|
||||
"sequencer_service_metrics",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@ -9503,16 +9505,15 @@ dependencies = [
|
||||
"logos-blockchain-key-management-system-service",
|
||||
"logos-blockchain-zone-sdk",
|
||||
"mempool",
|
||||
"metrics",
|
||||
"num-bigint 0.4.6",
|
||||
"ping_core",
|
||||
"programs",
|
||||
"rand 0.8.6",
|
||||
"risc0-zkvm",
|
||||
"sequencer_core_metrics",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"storage",
|
||||
"strum 0.28.0",
|
||||
"system_accounts",
|
||||
"tempfile",
|
||||
"test_programs",
|
||||
@ -9524,6 +9525,15 @@ dependencies = [
|
||||
"vault_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequencer_core_metrics"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"metrics",
|
||||
"strum 0.28.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequencer_service"
|
||||
version = "0.1.0"
|
||||
@ -9540,16 +9550,23 @@ dependencies = [
|
||||
"lee",
|
||||
"log",
|
||||
"mempool",
|
||||
"metrics",
|
||||
"metrics-exporter-prometheus",
|
||||
"programs",
|
||||
"sequencer_core",
|
||||
"sequencer_service_metrics",
|
||||
"sequencer_service_protocol",
|
||||
"sequencer_service_rpc",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequencer_service_metrics"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"metrics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequencer_service_protocol"
|
||||
version = "0.1.0"
|
||||
|
||||
@ -18,9 +18,11 @@ members = [
|
||||
"lez/system_accounts",
|
||||
"lez/chain_state",
|
||||
"lez/sequencer/core",
|
||||
"lez/sequencer/core/metrics",
|
||||
"lez/sequencer/service",
|
||||
"lez/sequencer/service/protocol",
|
||||
"lez/sequencer/service/rpc",
|
||||
"lez/sequencer/service/metrics",
|
||||
"lez/indexer/core",
|
||||
"lez/indexer/service",
|
||||
"lez/indexer/service/protocol",
|
||||
@ -79,8 +81,10 @@ mempool = { path = "lez/mempool" }
|
||||
storage = { path = "lez/storage" }
|
||||
key_protocol = { path = "lee/key_protocol" }
|
||||
sequencer_core = { path = "lez/sequencer/core" }
|
||||
sequencer_core_metrics = { path = "lez/sequencer/core/metrics" }
|
||||
sequencer_service_protocol = { path = "lez/sequencer/service/protocol" }
|
||||
sequencer_service_rpc = { path = "lez/sequencer/service/rpc" }
|
||||
sequencer_service_metrics = { path = "lez/sequencer/service/metrics" }
|
||||
sequencer_service = { path = "lez/sequencer/service" }
|
||||
indexer_core = { path = "lez/indexer/core" }
|
||||
indexer_service = { path = "lez/indexer/service" }
|
||||
|
||||
@ -12,6 +12,7 @@ lee.workspace = true
|
||||
lee_core.workspace = true
|
||||
chain_state.workspace = true
|
||||
common.workspace = true
|
||||
sequencer_core_metrics = { workspace = true, features = ["writing"] }
|
||||
storage.workspace = true
|
||||
mempool.workspace = true
|
||||
logos-blockchain-zone-sdk.workspace = true
|
||||
@ -34,7 +35,6 @@ humantime-serde.workspace = true
|
||||
tempfile.workspace = true
|
||||
chrono.workspace = true
|
||||
log.workspace = true
|
||||
metrics.workspace = true
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
tokio-util.workspace = true
|
||||
rand.workspace = true
|
||||
@ -46,7 +46,6 @@ num-bigint.workspace = true
|
||||
risc0-zkvm.workspace = true
|
||||
futures.workspace = true
|
||||
itertools.workspace = true
|
||||
strum.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
19
lez/sequencer/core/metrics/Cargo.toml
Normal file
19
lez/sequencer/core/metrics/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "sequencer_core_metrics"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
# Enable metrics writing
|
||||
writing = ["dep:common", "dep:metrics", "dep:strum"]
|
||||
|
||||
[dependencies]
|
||||
common = { workspace = true, optional = true }
|
||||
|
||||
metrics = { workspace = true, optional = true }
|
||||
strum = { workspace = true, optional = true }
|
||||
9
lez/sequencer/core/metrics/src/lib.rs
Normal file
9
lez/sequencer/core/metrics/src/lib.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//! This crate provides all metrics exposed by the sequencer core crate.
|
||||
|
||||
#[cfg(feature = "writing")]
|
||||
pub use writing::*;
|
||||
|
||||
pub mod names;
|
||||
|
||||
#[cfg(feature = "writing")]
|
||||
pub mod writing;
|
||||
6
lez/sequencer/core/metrics/src/names.rs
Normal file
6
lez/sequencer/core/metrics/src/names.rs
Normal file
@ -0,0 +1,6 @@
|
||||
pub const BLOCK_CREATION_TIME: &str = "block_creation_time";
|
||||
pub const BLOCK_COUNT: &str = "block_count";
|
||||
pub const MEMPOOL_SIZE: &str = "mempool_size";
|
||||
pub const MEMPOOL_TRANSACTION_APPLICATION_TIME: &str = "mempool_transaction_application_time";
|
||||
pub const TRANSACTIONS_PER_BLOCK: &str = "transactions_per_block";
|
||||
pub const FAILED_TRANSACTION_COUNT: &str = "failed_transaction_count";
|
||||
@ -1,5 +1,3 @@
|
||||
//! This module provides all metrics exposed by the sequencer core crate.
|
||||
|
||||
#![expect(
|
||||
clippy::cast_precision_loss,
|
||||
clippy::as_conversions,
|
||||
@ -11,15 +9,12 @@ use std::time::Duration;
|
||||
use common::transaction::TxKind;
|
||||
use metrics::{Counter, Unit, counter, gauge, histogram};
|
||||
|
||||
use crate::TransactionOrigin;
|
||||
use crate::names;
|
||||
|
||||
mod names {
|
||||
pub const BLOCK_CREATION_TIME: &str = "block_creation_time";
|
||||
pub const BLOCK_COUNT: &str = "block_count";
|
||||
pub const MEMPOOL_SIZE: &str = "mempool_size";
|
||||
pub const MEMPOOL_TRANSACTION_APPLICATION_TIME: &str = "mempool_transaction_application_time";
|
||||
pub const TRANSACTIONS_PER_BLOCK: &str = "transactions_per_block";
|
||||
pub const FAILED_TRANSACTION_COUNT: &str = "failed_transaction_count";
|
||||
#[derive(Clone, Copy, strum::IntoStaticStr)]
|
||||
pub enum TransactionOrigin {
|
||||
User,
|
||||
Sequencer,
|
||||
}
|
||||
|
||||
pub fn record_block_creation_time(duration: Duration) {
|
||||
@ -50,7 +50,6 @@ pub mod block_publisher;
|
||||
pub mod block_store;
|
||||
pub mod config;
|
||||
pub mod cross_zone_watcher;
|
||||
mod metrics;
|
||||
|
||||
#[cfg(feature = "mock")]
|
||||
pub mod mock;
|
||||
@ -73,7 +72,7 @@ const RETIRE_DISPATCH_AFTER_FAILURES: u32 = 3;
|
||||
const MAX_DISPATCHES_PER_BLOCK: usize = 16;
|
||||
|
||||
/// The origin of a transaction.
|
||||
#[derive(Clone, Copy, strum::IntoStaticStr)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum TransactionOrigin {
|
||||
/// Basic transactions submitted by users via RPC.
|
||||
User,
|
||||
@ -81,6 +80,15 @@ pub enum TransactionOrigin {
|
||||
Sequencer,
|
||||
}
|
||||
|
||||
impl From<TransactionOrigin> for sequencer_core_metrics::TransactionOrigin {
|
||||
fn from(origin: TransactionOrigin) -> Self {
|
||||
match origin {
|
||||
TransactionOrigin::User => Self::User,
|
||||
TransactionOrigin::Sequencer => Self::Sequencer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, BorshDeserialize)]
|
||||
struct DepositMetadata {
|
||||
recipient_id: lee::AccountId,
|
||||
@ -300,7 +308,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
watchers,
|
||||
};
|
||||
|
||||
crate::metrics::set_block_count(sequencer_core.chain_height());
|
||||
sequencer_core_metrics::set_block_count(sequencer_core.chain_height());
|
||||
|
||||
(sequencer_core, mempool_handle)
|
||||
}
|
||||
@ -805,7 +813,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
let clock_tx = clock_invocation(new_block_timestamp);
|
||||
let clock_lee_tx = LeeTransaction::Public(clock_tx.clone());
|
||||
|
||||
crate::metrics::record_mempool_size(self.mempool.len());
|
||||
sequencer_core_metrics::record_mempool_size(self.mempool.len());
|
||||
// Everything drained from the store first, then user work. `from_store`
|
||||
// is not the same as a `Sequencer` origin: it says the transaction has a
|
||||
// record behind it and so needs no requeue, where the origin only says
|
||||
@ -885,8 +893,8 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
new_block_timestamp,
|
||||
&mut withdrawals,
|
||||
);
|
||||
crate::metrics::record_mempool_transaction_application_time(
|
||||
origin,
|
||||
sequencer_core_metrics::record_mempool_transaction_application_time(
|
||||
origin.into(),
|
||||
tx.kind(),
|
||||
before_tx_apply.elapsed(),
|
||||
);
|
||||
@ -894,7 +902,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
if applied {
|
||||
valid_transactions.push(tx);
|
||||
} else {
|
||||
crate::metrics::increment_failed_transaction_count();
|
||||
sequencer_core_metrics::increment_failed_transaction_count();
|
||||
// A failed transaction is simply left out of the block, except a
|
||||
// dispatch: that one is re-fed from the store every turn, so one
|
||||
// that can never execute would fail on every block for ever.
|
||||
@ -910,7 +918,7 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
.transition_from_public_transaction(&clock_tx, new_block_height, new_block_timestamp)
|
||||
.context("Clock transaction failed. Aborting block production.")?;
|
||||
valid_transactions.push(clock_lee_tx);
|
||||
crate::metrics::record_transactions_per_block(valid_transactions.len());
|
||||
sequencer_core_metrics::record_transactions_per_block(valid_transactions.len());
|
||||
|
||||
let hashable_data = HashableBlockData {
|
||||
block_id: new_block_height,
|
||||
@ -929,8 +937,8 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
|
||||
now.elapsed().as_secs()
|
||||
);
|
||||
|
||||
crate::metrics::record_block_creation_time(now.elapsed());
|
||||
crate::metrics::increment_block_count();
|
||||
sequencer_core_metrics::record_block_creation_time(now.elapsed());
|
||||
sequencer_core_metrics::increment_block_count();
|
||||
|
||||
Ok(BlockWithMeta { block, withdrawals })
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ mempool.workspace = true
|
||||
sequencer_core = { workspace = true, features = ["testnet"] }
|
||||
sequencer_service_protocol.workspace = true
|
||||
sequencer_service_rpc = { workspace = true, features = ["server"] }
|
||||
sequencer_service_metrics = { workspace = true, features = ["writing"] }
|
||||
programs.workspace = true
|
||||
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
@ -22,7 +23,6 @@ anyhow.workspace = true
|
||||
env_logger.workspace = true
|
||||
hex.workspace = true
|
||||
log.workspace = true
|
||||
metrics.workspace = true
|
||||
metrics-exporter-prometheus.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
|
||||
16
lez/sequencer/service/metrics/Cargo.toml
Normal file
16
lez/sequencer/service/metrics/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "sequencer_service_metrics"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
# Enable metrics writing
|
||||
writing = ["dep:metrics"]
|
||||
|
||||
[dependencies]
|
||||
metrics = { workspace = true, optional = true }
|
||||
9
lez/sequencer/service/metrics/src/lib.rs
Normal file
9
lez/sequencer/service/metrics/src/lib.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//! This crate provides all metrics exposed by the sequencer core crate.
|
||||
|
||||
#[cfg(feature = "writing")]
|
||||
pub use writing::*;
|
||||
|
||||
pub mod names;
|
||||
|
||||
#[cfg(feature = "writing")]
|
||||
pub mod writing;
|
||||
1
lez/sequencer/service/metrics/src/names.rs
Normal file
1
lez/sequencer/service/metrics/src/names.rs
Normal file
@ -0,0 +1 @@
|
||||
pub const SUBMITTED_TRANSACTION_COUNT: &str = "submitted_transaction_count";
|
||||
@ -1,10 +1,6 @@
|
||||
//! This module provides all metrics exposed by the sequencer service crate.
|
||||
|
||||
use metrics::{Unit, counter};
|
||||
|
||||
mod names {
|
||||
pub const SUBMITTED_TRANSACTION_COUNT: &str = "submitted_transaction_count";
|
||||
}
|
||||
use crate::names;
|
||||
|
||||
pub fn increment_submitted_transaction_count() {
|
||||
counter!(
|
||||
@ -21,7 +21,6 @@ use sequencer_service_rpc::RpcServer as _;
|
||||
use tokio::{sync::Mutex, task::JoinHandle};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
mod metrics;
|
||||
pub mod service;
|
||||
|
||||
const REQUEST_BODY_MAX_SIZE: ByteSize = ByteSize::mib(10);
|
||||
|
||||
@ -93,7 +93,7 @@ impl<BC: BlockPublisherTrait + Send + Sync + 'static> sequencer_service_rpc::Rpc
|
||||
.await
|
||||
.expect("Mempool is closed, this is a bug");
|
||||
|
||||
crate::metrics::increment_submitted_transaction_count();
|
||||
sequencer_service_metrics::increment_submitted_transaction_count();
|
||||
|
||||
Ok(tx_hash)
|
||||
}
|
||||
|
||||
@ -8,6 +8,9 @@ license = { workspace = true }
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
sequencer_core_metrics.workspace = true
|
||||
sequencer_service_metrics.workspace = true
|
||||
|
||||
serde = { workspace = true, features = ["derive", "alloc"] }
|
||||
serde_json.workspace = true
|
||||
json-pretty-compact = "0.1.2"
|
||||
|
||||
@ -16,18 +16,6 @@ use dashboard_gen::{
|
||||
use json_pretty_compact::PrettyCompactFormatter;
|
||||
use serde::Serialize as _;
|
||||
|
||||
// Rendered Prometheus metric names. In a real setup these would be re-exported
|
||||
// from `sequencer_core::metrics` (base name + unit/counter suffix rule) so that
|
||||
// a rename in the recorder is a compile error here — that is the whole point of
|
||||
// generating dashboards from the same codebase that emits the metrics.
|
||||
const BLOCK_COUNT: &str = "block_count_total";
|
||||
const BLOCK_CREATION_TIME: &str = "block_creation_time_seconds";
|
||||
const TX_APPLY_TIME: &str = "mempool_transaction_application_time_seconds";
|
||||
const MEMPOOL_SIZE: &str = "mempool_size";
|
||||
const TX_PER_BLOCK: &str = "transactions_per_block";
|
||||
const SUBMITTED_TX: &str = "submitted_transaction_count_total";
|
||||
const FAILED_TX: &str = "failed_transaction_count_total";
|
||||
|
||||
const PERCENTILES: &[u32] = &[50, 90, 95, 99];
|
||||
|
||||
fn sequencer_dashboard() -> Dashboard {
|
||||
@ -41,11 +29,16 @@ fn sequencer_dashboard() -> Dashboard {
|
||||
.unit("short")
|
||||
.decimals(0)
|
||||
.color(Color::fixed("blue"))
|
||||
.target(Target::new(BLOCK_COUNT).legend("height")),
|
||||
.target(
|
||||
Target::new(sequencer_core_metrics::names::BLOCK_COUNT).legend("height"),
|
||||
),
|
||||
Panel::timeseries("Block production rate")
|
||||
.width(18)
|
||||
.unit("short")
|
||||
.target(rate_per_min(BLOCK_COUNT, "blocks/min")),
|
||||
.target(rate_per_min(
|
||||
sequencer_core_metrics::names::BLOCK_COUNT,
|
||||
"blocks/min",
|
||||
)),
|
||||
],
|
||||
)
|
||||
.row(
|
||||
@ -53,8 +46,11 @@ fn sequencer_dashboard() -> Dashboard {
|
||||
[Panel::timeseries("Block creation time")
|
||||
.width(24)
|
||||
.unit("s")
|
||||
.targets(percentiles(BLOCK_CREATION_TIME, PERCENTILES))
|
||||
.target(avg(BLOCK_CREATION_TIME))
|
||||
.targets(percentiles(
|
||||
sequencer_core_metrics::names::BLOCK_CREATION_TIME,
|
||||
PERCENTILES,
|
||||
))
|
||||
.target(avg(sequencer_core_metrics::names::BLOCK_CREATION_TIME))
|
||||
.with_override(
|
||||
FieldOverride::by_name("avg")
|
||||
.dashed_line()
|
||||
@ -68,7 +64,7 @@ fn sequencer_dashboard() -> Dashboard {
|
||||
.width(12)
|
||||
.unit("s")
|
||||
.targets(percentiles_labeled(
|
||||
TX_APPLY_TIME,
|
||||
sequencer_core_metrics::names::MEMPOOL_TRANSACTION_APPLICATION_TIME,
|
||||
PERCENTILES,
|
||||
" · {{kind}} · {{origin}}",
|
||||
)),
|
||||
@ -76,7 +72,10 @@ fn sequencer_dashboard() -> Dashboard {
|
||||
.width(12)
|
||||
.unit("short")
|
||||
.span_nulls()
|
||||
.target(Target::new(MEMPOOL_SIZE).legend("mempool size")),
|
||||
.target(
|
||||
Target::new(sequencer_core_metrics::names::MEMPOOL_SIZE)
|
||||
.legend("mempool size"),
|
||||
),
|
||||
],
|
||||
)
|
||||
.row(
|
||||
@ -85,8 +84,11 @@ fn sequencer_dashboard() -> Dashboard {
|
||||
Panel::timeseries("Transactions per block")
|
||||
.width(12)
|
||||
.unit("short")
|
||||
.targets(percentiles(TX_PER_BLOCK, PERCENTILES))
|
||||
.target(avg(TX_PER_BLOCK))
|
||||
.targets(percentiles(
|
||||
sequencer_core_metrics::names::TRANSACTIONS_PER_BLOCK,
|
||||
PERCENTILES,
|
||||
))
|
||||
.target(avg(sequencer_core_metrics::names::TRANSACTIONS_PER_BLOCK))
|
||||
.with_override(
|
||||
FieldOverride::by_name("avg")
|
||||
.dashed_line()
|
||||
@ -95,8 +97,14 @@ fn sequencer_dashboard() -> Dashboard {
|
||||
Panel::timeseries("Transaction throughput (per minute)")
|
||||
.width(12)
|
||||
.unit("short")
|
||||
.target(rate_per_min(SUBMITTED_TX, "submitted"))
|
||||
.target(rate_per_min(FAILED_TX, "failed"))
|
||||
.target(rate_per_min(
|
||||
sequencer_service_metrics::names::SUBMITTED_TRANSACTION_COUNT,
|
||||
"submitted",
|
||||
))
|
||||
.target(rate_per_min(
|
||||
sequencer_core_metrics::names::FAILED_TRANSACTION_COUNT,
|
||||
"failed",
|
||||
))
|
||||
.with_override(FieldOverride::by_name("failed").color(Color::fixed("red")))
|
||||
.with_override(
|
||||
FieldOverride::by_name("submitted").color(Color::fixed("green")),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user