You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: document missing metrics and fix gean repo link (lambdaclass#397)
## Summary
Reconciles `docs/metrics.md` with the implementation and the pinned
[leanMetrics spec](https://github.com/leanEthereum/leanMetrics). 11
implemented metrics were undocumented; 2 spec metrics ethlambda doesn't
implement were missing entirely.
### Metrics doc changes
- **New Block Production Metrics section** (all in spec, supported):
`lean_block_aggregated_payloads`,
`lean_block_building_payload_aggregation_time_seconds`,
`lean_block_building_time_seconds`, `lean_block_building_success_total`,
`lean_block_building_failures_total`
- **Fork-Choice:** `lean_node_sync_status`
(`status=idle,syncing,synced`)
- **Network:** `lean_gossip_mesh_peers` (`client` label)
- **State Transition:** spec's `lean_justified_slot` /
`lean_finalized_slot` added as unsupported (ethlambda only emits the
`latest_*` variants)
- **Custom (non-leanMetrics):** new Storage subsection
(`lean_table_bytes`) and Attestation Aggregate Coverage subsection
(`lean_attestation_aggregate_coverage_validators` / `_subnets` /
`_diff_validators`)
Verified existing rows for drift: `finalizations_total`, `node_info`,
and reqresp `protocol` labels all match the code.
### Other
- `coverage.rs`: `TODO` flagging the reserved-but-unpopulated per-subnet
(`subnet_N`) breakdown, matching the note in the doc
- `introduction.md`: fix stale gean repo URL (`devlongs/gean` ->
`geanlabs/gean`), consistent with the CLAUDE.md fix in lambdaclass#393
## Test plan
Docs + one comment change only; no code behavior affected.
|`lean_pq_sig_aggregated_signatures_building_time_seconds`| Histogram | Time taken to build an aggregated attestation signature | On aggregated signature production || 0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4 | ✅ |
31
31
|`lean_pq_sig_aggregated_signatures_verification_time_seconds`| Histogram | Time taken to verify an aggregated attestation signature | On aggregated signature verification || 0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4 | ✅ |
32
32
33
+
## Block Production Metrics
34
+
35
+
| Name | Type | Usage | Sample collection event | Labels | Buckets | Supported |
|`lean_block_aggregated_payloads`| Histogram | Number of `aggregated_payloads` in a block | On block production || 1, 2, 4, 8, 16, 32, 64, 128 | ✅ |
38
+
|`lean_block_building_payload_aggregation_time_seconds`| Histogram | Time taken to build `aggregated_payloads` during block building | On block production || 0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4 | ✅ |
39
+
|`lean_block_building_time_seconds`| Histogram | Time taken to build a block | On block production || 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 0.75, 1 | ✅ |
40
+
|`lean_block_building_success_total`| Counter | Successful block builds | On block production ||| ✅ |
41
+
|`lean_block_building_failures_total`| Counter | Failed block builds (error building the block, signing the block root, or processing it locally) | On block production failure ||| ✅ |
42
+
33
43
## Fork-Choice Metrics
34
44
35
45
| Name | Type | Usage | Sample collection event | Labels | Buckets | Supported |
|`lean_latest_justified_slot`| Gauge | Latest justified slot | On state transition ||| ✅ |
57
68
|`lean_latest_finalized_slot`| Gauge | Latest finalized slot | On state transition ||| ✅ |
69
+
|`lean_justified_slot`| Gauge | Current justified slot | On state transition ||| ❌ |
70
+
|`lean_finalized_slot`| Gauge | Current finalized slot | On state transition ||| ❌ |
58
71
|`lean_finalizations_total`| Counter | Total number of finalization attempts | On finalization attempt | result=success,error || ✅ |
59
72
|`lean_state_transition_time_seconds`| Histogram | Time to process state transition | On state transition || 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 2.5, 3, 4 | ✅ |
60
73
|`lean_state_transition_slots_processed_total`| Counter | Total number of processed slots | On state transition process slots ||| ✅ |
|`lean_connected_peers`| Gauge | Number of connected peers | On scrape | client=ethlambda,grandine,lantern,lighthouse,qlean,ream,zeam | ✅(*) |
94
+
|`lean_gossip_mesh_peers`| Gauge | Number of peers in the gossipsub mesh | On scrape | client=`<name>_<N>`,unknown (ex. zeam_0) | ✅(*) |
81
95
|`lean_peer_connection_events_total`| Counter | Total number of peer connection events | On peer connection | direction=inbound,outbound<br>result=success,timeout,error | ✅ |
82
96
|`lean_peer_disconnection_events_total`| Counter | Total number of peer disconnection events | On peer disconnection | direction=inbound,outbound<br>reason=timeout,remote_close,local_close,error | ✅ |
83
97
@@ -101,6 +115,26 @@ The metrics below are not part of the [leanMetrics specification](https://github
101
115
|`lean_reqresp_request_size_bytes`| Histogram | Bytes size of a req/resp request (raw SSZ or snappy on-wire) | On req/resp request send/receive | protocol=status,blocks_by_root<br>compression=raw,snappy | 64, 128, 256, 512, 1024, 4096, 16384, 65536 |
102
116
|`lean_reqresp_response_chunk_size_bytes`| Histogram | Bytes size of a single req/resp response chunk (raw SSZ or snappy on-wire) | On req/resp response chunk send/receive | protocol=status,blocks_by_root<br>compression=raw,snappy | 128, 1024, 10000, 100000, 500000, 1000000, 5000000, 10000000 |
103
117
118
+
### Storage
119
+
120
+
| Name | Type | Usage | Sample collection event | Labels |
|`lean_table_bytes`| Gauge | Estimated byte size of a storage table (key + value bytes) | After each processed block (one update per table); retains its previous value on empty slots | table=`<table_name>`|
123
+
124
+
### Attestation Aggregate Coverage
125
+
126
+
Observability into how many validators/subnets are covered by the attestations the node has aggregated, broken down by pipeline section (the `section` label). The slot is the X-axis. These are sampled roughly once per slot, but emission is gated by the section's source data, so a gauge can retain its previous value:
127
+
128
+
-`timely`, `late`, `block`, `combined` and the `diff_validators` directions are emitted on block import, and **only when the canonical head block carries that round's votes** (otherwise the round is skipped and prior values are kept).
129
+
-`agg_start_new` is emitted at interval 2, right before fork-choice aggregation runs.
130
+
-`proposal_combined` is emitted only when this node proposes a block.
131
+
132
+
| Name | Type | Usage | Sample collection event | Labels |
|`lean_attestation_aggregate_coverage_validators`| Gauge | Validator coverage in attestation aggregate reports | Per round, per section (see note above) | section=timely,late,block,combined,agg_start_new,proposal_combined<br>subnet=combined (per-subnet breakdown reserved, not yet populated) |
135
+
|`lean_attestation_aggregate_coverage_subnets`| Gauge | Number of covered subnets in attestation aggregate reports | Per round, per section (see note above) | section=timely,late,block,combined,agg_start_new,proposal_combined |
136
+
|`lean_attestation_aggregate_coverage_diff_validators`| Gauge | Validators in the symmetric difference between block-included aggregates and locally-aggregated timely aggregates for the same slot | On block import, when the head carries the round's votes (see note above) | direction=block_only,timely_only |
137
+
104
138
---
105
139
106
140
✅(*) **Partial support**: These metrics are implemented but not collected "on scrape" as the spec requires. They are updated on specific events (e.g., on tick, on block processing) rather than being computed fresh on each Prometheus scrape.
0 commit comments