fix(observability): correct LoopoverOrbExportErrorRateHigh's stale runbook metric name - #6094
Conversation
…nbook metric name (JSONbored#5816) The runbook told operators to compare loopover_orb_events_recorded_total against _exported_total to confirm a stuck exporter, but no "recorded" counter was ever registered -- only loopover_orb_events_exported_total and loopover_orb_export_errors_total exist (src/selfhost/orb-collector.ts). Rephrases the runbook to point at the two real metrics already in the alert's own expr. Adds a general regression check (test/unit/alerts-metric-name-references.test.ts) that scans every loopover_*-shaped token in every alert's annotation text in prometheus/rules/alerts.yml and asserts it resolves to a registered metric (src/selfhost/metrics.ts), a documented external prefix (backup exporter, opt-in D1 probe, miner CLI), or a recognized label-wildcard family -- so a future stale/renamed metric reference in annotation prose fails CI instead of shipping unnoticed.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6094 +/- ##
==========================================
+ Coverage 95.23% 95.24% +0.01%
==========================================
Files 595 595
Lines 47013 47032 +19
Branches 15015 15012 -3
==========================================
+ Hits 44771 44794 +23
Misses 1493 1493
+ Partials 749 745 -4
Flags with carried forward coverage won't be shown. Click here to find out more. |
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-15 09:21:08 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 5 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Summary
LoopoverOrbExportErrorRateHigh's runbook annotation inprometheus/rules/alerts.ymltold operators to compareloopover_orb_events_recorded_totalagainst_exported_totalto confirm a stuck exporter, but no "recorded" counter was ever registered — onlyloopover_orb_events_exported_totalandloopover_orb_export_errors_totalexist (src/selfhost/orb-collector.ts,src/selfhost/metrics.ts). An operator paged by this alert who followed the runbook literally got an empty Prometheus series.expr, per the issue's own suggested fix — no other change to the alert.test/unit/alerts-metric-name-references.test.ts) that scans everyloopover_*-shaped token in every alert's annotation text (summary/description/runbook) acrossprometheus/rules/alerts.ymland asserts each one resolves to a registered metric (src/selfhost/metrics.ts'sDEFAULT_METRIC_META), a documented external-source prefix (loopover_backup_*the backup exporter,loopover_d1_*the opt-in Cloudflare D1 probe,loopover_miner_*the miner CLI's own pushed metrics), or a recognized label-wildcard family reference (a trailing*, e.g.loopover_jobs_rate_limit_*).Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Closes #5816
Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateIf any required check was skipped, explain why:
npm run test:cichain's localtsc --noEmitstep OOM-crashes reproducibly. This PR changes zero application.ts/.jssource logic — only a YAML annotation string and one new self-contained test file (readFileSync/yaml'sparse, mirroringtest/unit/alerts-job-failure-ratio-formula.test.ts's ownalerts.yml-parsing pattern already in the suite). What I could run locally is green:actionlint,db:migrations:check,npm run selfhost:validate-observability(the existing PromQL/dashboard validator, confirms the YAML edit is still valid),npm audit, and the new test file plus a siblingalerts-*.test.tsin isolation vianpx vitest run— all pass, including the fail-case fixture proving the new check works. CI'svalidate-code/validate-testsjobs run on GitHub's own isolated runners with no such contention and will independently confirm the rest (typecheck included) before merge — the same pattern used successfully for PR fix(selfhost): correct stale gittensory_ metric names in .env.example #6079 earlier this session.Safety
UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.Not applicable: this is an observability-config + test-only change, no UI/auth/session/API surface touched.
Notes
loopover_orb_events_recorded_totalmetric — the runbook is corrected to describe real, already-registered metrics instead.