Skip to content

feat(metrics): add sequencer metrics & grafana dashboard generation tool - #651

Open
Arjentix wants to merge 15 commits into
devfrom
arjentix/metrics
Open

feat(metrics): add sequencer metrics & grafana dashboard generation tool#651
Arjentix wants to merge 15 commits into
devfrom
arjentix/metrics

Conversation

@Arjentix

@Arjentix Arjentix commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

🎯 Purpose

This PR introduces metrics to the Sequencer as well as a tool to generate Grafana dashboards with code-first approach.

⚙️ Approach

  • Add two metric crates: one for sequencer_core and one for sequencer_service
  • Add tool/dashboard_gen which generates Grafana dashboard from rust specification
  • Add docker compose and just setup to run Prometheus + Grafana setup locally
  • Add documentation as metrics.md
  • Add CI job to ensure grafana dashboard is up to date with rust code

Screenshot (not full):

image

🧪 How to Test

  • Run the whole setup with just
  • Open http://localhost:3000 and go to the Sequencer dashboard
  • Play around, submit some transactions, see metrics changing

🔗 Dependencies

None

🔜 Future Work

  • Indexer metrics
  • dashboard_gen tool only supports things we need right now, so on every new non-supported Grafana json syntax we need to expand it

📋 PR Completion Checklist

  • Complete PR description
  • Implement the core functionality
    - [ ] Add/update tests
  • Add/update documentation and inline comments

@Arjentix Arjentix self-assigned this Jul 28, 2026
Comment thread lez/sequencer/core/metrics/src/names.rs
Comment thread lez/sequencer/service/src/main.rs
Comment thread lez/common/src/transaction.rs
Comment thread lez/sequencer/service/metrics/src/lib.rs Outdated
Comment thread docker-compose.yml

@erhant erhant left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM nice work! few small comments

@moudyellaz moudyellaz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks! Left some minor comments/questions.

);

sequencer_core_metrics::record_block_creation_time(now.elapsed());
sequencer_core_metrics::increment_blocks_total();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

increment_blocks_total() fires in build_block_from_mempool before publish, so it counts build attempts, parked blocks included, and misses peer-adopted ones. Since startup seeds it from chain_height(), "Chain height" drifts once a second sequencer produces. Could we move it to record_produced_block's Applied arm plus the follow path, or rename it blocks_produced_total?

#[must_use]
pub fn rate_per_min(metric: &str, legend: &str) -> Target {
Target::new(format!("rate({metric}[1m]) * 60")).legend(legend)
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rate({metric}[{RATE_WINDOW}]) * 60 instead?

Deserialize,
BorshSerialize,
BorshDeserialize,
strum::IntoStaticStr,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe drop IntoStaticStr and EnumIter since they are not used?

)?;
sequencer_core_metrics::record_mempool_transaction_application_time(
origin.into(),
tx.kind().into(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe record this only when applied, or add a status label, so failed applications do not skew the histogram?

/// A percentile as its `histogram_quantile` argument, derived without float
/// math: zero-pad to two digits then drop trailing zeros (50 → `0.5`).
fn quantile(percentile: u32) -> String {
let quantile = format!("0.{percentile:02}");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quantile(100) gives 0.1 and quantile(0) gives 0., maybe assert 1..=99 like the default check above?

@Pravdyvy Pravdyvy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. One comment, probably a future work if it is not trivial.

pub async fn start_from_config(
config: SequencerConfig,
) -> (Self, MemPoolHandle<(TransactionOrigin, LeeTransaction)>) {
sequencer_core_metrics::init();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we make metrics collection mandatory for every sequencer. For this PR it is fine, but it would be good to make it configurable. Not providing metrics_address in config should be a sufficient trigger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants