PR: #34 (feat/09-health-scanner)
File: crates/charon-scanner/src/scanner.rs, crates/charon-cli/src/main.rs
Problem: PRD review focus item 11 — borrowers_in_bucket{bucket}, scan_duration_seconds{bucket}, transitions_total must be emitted as Prometheus metrics.
PR emits all three values only via tracing::info! in main.rs (healthy, near_liq, liquidatable, scan_ms fields on "venus scan" span). These are log lines, not scraped metrics. Grafana dashboard JSON (commit ba75664) references these metric names; without Prometheus counters/gauges/histograms, dashboard will show no data.
No transitions_total counter either. Scanner overwrites bucket silently in upsert(); does not detect when borrower moves between buckets, so transition rate — key leading indicator of market stress — invisible to ops.
Fix: Introduce metrics module in charon-scanner using metrics crate (workspace dep or add). In upsert(), compare old bucket to new bucket before overwriting; if changed, increment transitions_total{from, to}. Expose gauge borrowers_in_bucket{bucket} updated in bucket_counts(). Record scan_duration_seconds{bucket} histogram from elapsed time already captured in main.rs.
PR: #34 (feat/09-health-scanner)
File: crates/charon-scanner/src/scanner.rs, crates/charon-cli/src/main.rs
Problem: PRD review focus item 11 —
borrowers_in_bucket{bucket},scan_duration_seconds{bucket},transitions_totalmust be emitted as Prometheus metrics.PR emits all three values only via
tracing::info!in main.rs (healthy, near_liq, liquidatable, scan_msfields on "venus scan" span). These are log lines, not scraped metrics. Grafana dashboard JSON (commit ba75664) references these metric names; without Prometheus counters/gauges/histograms, dashboard will show no data.No
transitions_totalcounter either. Scanner overwrites bucket silently inupsert(); does not detect when borrower moves between buckets, so transition rate — key leading indicator of market stress — invisible to ops.Fix: Introduce metrics module in charon-scanner using
metricscrate (workspace dep or add). Inupsert(), compare old bucket to new bucket before overwriting; if changed, incrementtransitions_total{from, to}. Expose gaugeborrowers_in_bucket{bucket}updated inbucket_counts(). Recordscan_duration_seconds{bucket}histogram from elapsed time already captured in main.rs.