Skip to content

Commit 16d54d6

Browse files
authored
chore: add additional metric to show time since last block (#27)
1 parent d5f0b78 commit 16d54d6

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,56 @@ When metrics are enabled, the following metrics are exposed:
150150
- **Labels**: `chain_id`, `type`
151151
- **Description**: Latest DA height for header and data submissions
152152

153+
### Block Time Metrics
154+
155+
### `ev_metrics_block_time_seconds`
156+
- **Type**: Histogram
157+
- **Labels**: `chain_id`
158+
- **Description**: Time between consecutive blocks with histogram buckets for accurate SLO calculations
159+
- **Buckets**: 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.5, 2 seconds
160+
161+
### `ev_metrics_block_time_summary_seconds`
162+
- **Type**: Summary
163+
- **Labels**: `chain_id`
164+
- **Description**: Block time with percentiles over a 60-second rolling window
165+
- **Note**: Will show NaN when no blocks have been received in the last 60 seconds
166+
167+
### `ev_metrics_time_since_last_block_seconds`
168+
- **Type**: Gauge
169+
- **Labels**: `chain_id`
170+
- **Description**: Seconds since last block was received. Use this metric for alerting on stale blocks.
171+
- **Alerting**: Alert when this value exceeds 60 seconds to detect block production issues before summary metrics show NaN
172+
173+
### `ev_metrics_block_time_slo_seconds`
174+
- **Type**: Gauge
175+
- **Labels**: `chain_id`, `quantile`
176+
- **Description**: SLO thresholds for block time
177+
- **Values**:
178+
- `0.5`: 2.0s
179+
- `0.9`: 3.0s
180+
- `0.95`: 4.0s
181+
- `0.99`: 5.0s
182+
183+
### `ev_metrics_block_receive_delay_seconds`
184+
- **Type**: Histogram
185+
- **Labels**: `chain_id`
186+
- **Description**: Delay between block creation and reception with histogram buckets
187+
- **Buckets**: 0.1, 0.25, 0.5, 1.0, 2.0, 3.0, 5.0, 10.0, 15.0, 30.0, 60.0 seconds
188+
189+
### `ev_metrics_block_receive_delay_slo_seconds`
190+
- **Type**: Gauge
191+
- **Labels**: `chain_id`, `quantile`
192+
- **Description**: SLO thresholds for block receive delay
193+
- **Values**:
194+
- `0.5`: 1.0s
195+
- `0.9`: 3.0s
196+
- `0.95`: 5.0s
197+
- `0.99`: 10.0s
198+
199+
### JSON-RPC Monitoring Metrics
200+
201+
When `--evm-rpc-url` is provided:
202+
153203
### `ev_metrics_jsonrpc_request_duration_seconds`
154204
- **Type**: Histogram
155205
- **Labels**: `chain_id`

pkg/exporters/verifier/verifier.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ func (e *exporter) ExportMetrics(ctx context.Context, m *metrics.Metrics) error
8989
case <-refreshTicker.C:
9090
// ensure that submission duration is always included in the 60 second window.
9191
m.RefreshSubmissionDuration()
92+
// update time since last block metric
93+
m.UpdateTimeSinceLastBlock()
9294
case header := <-headers:
9395
// record block arrival time for millisecond precision
9496
arrivalTime := time.Now()

pkg/metrics/metrics.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ type Metrics struct {
3333
BlockTime *prometheus.HistogramVec
3434
// BlockTimeSummary tracks block time with percentiles over a rolling window.
3535
BlockTimeSummary *prometheus.SummaryVec
36+
// TimeSinceLastBlock tracks seconds since last block was received.
37+
TimeSinceLastBlock *prometheus.GaugeVec
3638
// BlockReceiveDelay tracks the delay between block creation and reception with histogram buckets.
3739
BlockReceiveDelay *prometheus.HistogramVec
3840
// JsonRpcRequestDuration tracks the duration of JSON-RPC requests to the EVM node.
@@ -181,6 +183,14 @@ func NewWithRegistry(namespace string, registerer prometheus.Registerer) *Metric
181183
},
182184
[]string{"chain_id"},
183185
),
186+
TimeSinceLastBlock: factory.NewGaugeVec(
187+
prometheus.GaugeOpts{
188+
Namespace: namespace,
189+
Name: "time_since_last_block_seconds",
190+
Help: "seconds since last block was received",
191+
},
192+
[]string{"chain_id"},
193+
),
184194
BlockReceiveDelay: factory.NewHistogramVec(
185195
prometheus.HistogramOpts{
186196
Namespace: namespace,
@@ -554,6 +564,21 @@ func (m *Metrics) RecordBlockTime(chainID string, arrivalTime time.Time) {
554564

555565
// update last seen arrival time
556566
m.lastBlockArrivalTime[chainID] = arrivalTime
567+
// reset time since last block to 0
568+
m.TimeSinceLastBlock.WithLabelValues(chainID).Set(0)
569+
}
570+
571+
// UpdateTimeSinceLastBlock updates the time_since_last_block metric for all chains
572+
// should be called periodically to keep the metric current.
573+
func (m *Metrics) UpdateTimeSinceLastBlock() {
574+
m.mu.Lock()
575+
defer m.mu.Unlock()
576+
577+
now := time.Now()
578+
for chainID, lastArrival := range m.lastBlockArrivalTime {
579+
timeSince := now.Sub(lastArrival).Seconds()
580+
m.TimeSinceLastBlock.WithLabelValues(chainID).Set(timeSince)
581+
}
557582
}
558583

559584
// RecordBlockReceiveDelay records the delay between block creation and reception

0 commit comments

Comments
 (0)