feat(metrics): B1 live apply-phase Prometheus gauges - #192
Conversation
Snapshot heights can lag while process_block runs; these atomics give operators an honest in-progress / last-duration / last-height / age signal. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning Review limit reached
Next review available in: 57 seconds Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (47)
📝 WalkthroughWalkthroughAdds apply-phase metrics for block processing, propagates live values through node status, exposes four Prometheus gauges, and updates API test fixtures for the expanded ChangesApply-phase telemetry
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant SyncExecutor
participant ApplyPhaseMetrics
participant SnapshotReadState
participant Prometheus
SyncExecutor->>ApplyPhaseMetrics: record block apply outcome
SnapshotReadState->>ApplyPhaseMetrics: read live metrics
SnapshotReadState-->>Prometheus: provide ApiStatus values
Prometheus->>Prometheus: render apply gauges
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
🧹 Nitpick comments (3)
ergo-node/src/api_bridge.rs (1)
78-79: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winWiring looks correct; consider a dedicated regression test for the live overlay.
The overlay logic itself is correct (ordering, field mapping all line up with
ApplyPhaseMetrics). However, no test in this cohort exercisesstatus()with a non-defaultApplyPhaseMetrics—api_bridge/tests.rsonly ever passesApplyPhaseMetrics::default(). A test that callsapply_phase.begin()/success(height)then assertsstatus().apply_in_progress/last_apply_duration_ms/last_applied_height/last_apply_age_msreflect it would catch a future regression (e.g., a dropped field assignment) that the type system won't.Happy to draft this test if useful.
Also applies to: 257-271, 398-408
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ergo-node/src/api_bridge.rs` around lines 78 - 79, Add a regression test in the API bridge tests that uses a non-default ApplyPhaseMetrics, invokes begin() and success(height), then calls status() and asserts apply_in_progress, last_apply_duration_ms, last_applied_height, and last_apply_age_ms reflect the live metrics overlay. Keep existing default-metrics coverage unchanged.ergo-sync/src/apply_phase.rs (1)
21-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd
#[must_use]toApplyPhaseGuardto prevent silent misuse.Nothing stops a future call site from writing
self.apply_phase.begin();as a bare statement — the guard would be constructed and immediately dropped, defeating the "live in-progress" gauge for that call without any compiler warning. Both current call sites correctly bind the guard, but this is cheap insurance against regressions in new call sites.🛡️ Proposed fix
/// RAII: sets `in_progress` for the duration of one `process_block` call. +#[must_use] pub struct ApplyPhaseGuard<'a> { metrics: &'a ApplyPhaseMetrics, started: Instant, finished: bool, }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ergo-sync/src/apply_phase.rs` around lines 21 - 36, Add the #[must_use] attribute to the ApplyPhaseGuard struct so callers are warned when begin() returns a guard that is immediately discarded. Leave ApplyPhaseMetrics::begin and the guard’s existing behavior unchanged.ergo-api/tests/blocks_proof_for_tx_parity.rs (1)
40-66: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffConsider a shared
ApiStatustest default to avoid repeating this literal ~40 times.This PR touches every API test file to add four fields to the same struct literal. Deriving
DefaultforApiStatus(or adding atest_default()helper inergo-api) would let stubs use..ApiStatus::default()for unused fields, so future field additions don't require a fan-out edit across every test.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ergo-api/tests/blocks_proof_for_tx_parity.rs` around lines 40 - 66, Add a shared default construction path for ApiStatus, preferably by deriving or implementing Default in the ergo-api definition, then update the test stub’s status method to initialize only its meaningful overrides and fill remaining fields via ApiStatus::default(). Apply the shared pattern across affected API test stubs so future ApiStatus fields do not require repeated literal updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@ergo-api/tests/blocks_proof_for_tx_parity.rs`:
- Around line 40-66: Add a shared default construction path for ApiStatus,
preferably by deriving or implementing Default in the ergo-api definition, then
update the test stub’s status method to initialize only its meaningful overrides
and fill remaining fields via ApiStatus::default(). Apply the shared pattern
across affected API test stubs so future ApiStatus fields do not require
repeated literal updates.
In `@ergo-node/src/api_bridge.rs`:
- Around line 78-79: Add a regression test in the API bridge tests that uses a
non-default ApplyPhaseMetrics, invokes begin() and success(height), then calls
status() and asserts apply_in_progress, last_apply_duration_ms,
last_applied_height, and last_apply_age_ms reflect the live metrics overlay.
Keep existing default-metrics coverage unchanged.
In `@ergo-sync/src/apply_phase.rs`:
- Around line 21-36: Add the #[must_use] attribute to the ApplyPhaseGuard struct
so callers are warned when begin() returns a guard that is immediately
discarded. Leave ApplyPhaseMetrics::begin and the guard’s existing behavior
unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c6161ed7-deae-4f88-9a13-94a1b499fc3d
📒 Files selected for processing (52)
ergo-api/src/server.rsergo-api/src/types.rsergo-api/tests/blockchain_balance_routes.rsergo-api/tests/blockchain_block_routes.rsergo-api/tests/blockchain_box_range_route.rsergo-api/tests/blockchain_box_routes.rsergo-api/tests/blockchain_byaddress_routes.rsergo-api/tests/blockchain_byergotree_routes.rsergo-api/tests/blockchain_indexed_height.rsergo-api/tests/blockchain_scala_parity.rsergo-api/tests/blockchain_template_routes.rsergo-api/tests/blockchain_token_routes.rsergo-api/tests/blockchain_transaction_range_route.rsergo-api/tests/blockchain_tx_routes.rsergo-api/tests/blockchain_unspent_byaddress_routes.rsergo-api/tests/blocks_at_parity.rsergo-api/tests/blocks_header_ids_parity.rsergo-api/tests/blocks_id_parity.rsergo-api/tests/blocks_modifier_parity.rsergo-api/tests/blocks_proof_for_tx_parity.rsergo-api/tests/compat_blocks_submit_route.rsergo-api/tests/compat_submit_routes.rsergo-api/tests/difficulty_history_route.rsergo-api/tests/events_endpoint.rsergo-api/tests/extra_index_router_walk.rsergo-api/tests/host_schema.rsergo-api/tests/identity_schema.rsergo-api/tests/indexer_status_endpoint.rsergo-api/tests/mempool_overlay_oracle.rsergo-api/tests/mempool_source_schema.rsergo-api/tests/miner_stats_route.rsergo-api/tests/nipopow_routes_parity.rsergo-api/tests/openapi_native_runtime_mount.rsergo-api/tests/recent_blocks_route.rsergo-api/tests/router_layout.rsergo-api/tests/serve_shutdown.rsergo-api/tests/storage_rent_assets_route.rsergo-api/tests/submit_routes.rsergo-api/tests/v1_batch_routes.rsergo-api/tests/v1_boxes_tokens_addresses_routes.rsergo-api/tests/v1_chain_tx_routes.rsergo-api/tests/v1_light_stats_diag_routes.rsergo-api/tests/v1_mempool_routes.rsergo-api/tests/v1_operator_routes.rsergo-api/tests/v1_script_routes.rsergo-node/src/api_bridge.rsergo-node/src/api_bridge/tests.rsergo-node/src/node/boot.rsergo-node/src/snapshot.rsergo-sync/src/apply_phase.rsergo-sync/src/executor/mod.rsergo-sync/src/lib.rs
CI failed on openapi_native_matches_snapshot after B1 added the four apply gauges to ApiStatus. Co-authored-by: Cursor <cursoragent@cursor.com>
Review follow-ups: collapse test ApiStatus literals onto Default, cover live apply-phase overlay in SnapshotReadState::status, and mark ApplyPhaseGuard #[must_use]. ApiStatus already derived Default. Co-authored-by: Cursor <cursoragent@cursor.com>
Bump workspace version to 0.5.2 and promote the changelog: the complete v1 product API (#168-#185, #188), shadow validation as a production mode (#193-#195), the operator observability wave (#187, #190, #192, #194), two live accept-invalid consensus fixes (#176, #179), ErgoScript compiler byte-parity completion (#165-#167, #175), and the #160-#163 sync/recovery fixes. Full workspace gate run on the merge result. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BUh2DBnAPqThdYFZW5D8wx
Summary
ApplyPhaseMetricsatomics around bothprocess_blockcall sites so operators can see apply in progress without waiting for the next snapshot tick./metrics(and matchingApiStatusfields):apply_in_progress,last_apply_duration_ms,last_applied_height,last_apply_age_ms.SnapshotReadState::status()at boot.Test plan
cargo fmt --all -- --checkcargo clippy -p ergo-sync -p ergo-api -p ergo-node --all-targets --all-features -- -D warningscargo test -p ergo-sync --lib apply_phasecargo test -p ergo-node --lib api_bridgeergo-apifixture tests (router_layout,serve_shutdown, …)curl -s localhost:9053/metrics | grep ergo_node_applyMade with Cursor
Summary by CodeRabbit
New Features
/metricsendpoint and node status data.Tests