chore(api): emit explicit zero for IPNS-entries gauge on empty table#561
Conversation
collectGauges() resets cipherbox_ipns_entries_total and repopulates it from a
GROUP BY record_type query. With an empty folder_ipns table that query returns
zero rows, so reset() leaves the gauge with no series at all -- Prometheus then
serves the last non-zero sample through its staleness window and Grafana stat
panels stick at it, so a freshly-wiped environment mis-reports as N IPNS
entries (observed as a stale 43 after a staging reset).
Seed every known record type ('folder', 'file') to 0 after reset, then overlay
the real counts, so an empty table reports an explicit 0 per type. Adds a
regression test covering the empty and partial-population cases.
Internal metrics only -- no API surface change, so no api-client regen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SDNQVLoAw4DbPrPvtQPobh
Entire-Checkpoint: 3e3f489016fc
WalkthroughThe IPNS metrics collector now seeds known ChangesIPNS gauge zero seeding
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Release PreviewNo version bumps detected. All changes are in unversioned paths or use exempt commit types. |
Greptile SummaryThis PR fixes
Confidence Score: 5/5The metrics fix is minimal and correct; the unrelated CI guard removal is deliberate but unexplained. The core change is a small, well-tested seed loop that only affects internal Prometheus gauge reporting. The logic is sound: reset → seed known types to 0 → overlay real counts. Tests cover both the zero-state and partial-count paths. The unrelated removal of the stale release-as CI guard is worth clarifying but does not affect the correctness of any deployed code. .github/workflows/ci.yml — removal of the release-as CI guard is unexplained and unrelated to the stated PR scope. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Scheduler as setInterval (30s)
participant collectGauges
participant DB as PostgreSQL
participant gauge as ipnsEntriesTotal
Scheduler->>collectGauges: tick
collectGauges->>DB: GROUP BY record_type (folder_ipns)
DB-->>collectGauges: "[] (empty) or [{recordType, count}]"
collectGauges->>gauge: reset()
Note over collectGauges,gauge: NEW: seed known types to 0
collectGauges->>gauge: labels('folder').set(0)
collectGauges->>gauge: labels('file').set(0)
loop for each row returned
collectGauges->>gauge: labels(row.recordType).set(parseInt(row.count))
end
Note over gauge: Prometheus now always has an explicit series,
Note over gauge: no stale-window carry-over
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Scheduler as setInterval (30s)
participant collectGauges
participant DB as PostgreSQL
participant gauge as ipnsEntriesTotal
Scheduler->>collectGauges: tick
collectGauges->>DB: GROUP BY record_type (folder_ipns)
DB-->>collectGauges: "[] (empty) or [{recordType, count}]"
collectGauges->>gauge: reset()
Note over collectGauges,gauge: NEW: seed known types to 0
collectGauges->>gauge: labels('folder').set(0)
collectGauges->>gauge: labels('file').set(0)
loop for each row returned
collectGauges->>gauge: labels(row.recordType).set(parseInt(row.count))
end
Note over gauge: Prometheus now always has an explicit series,
Note over gauge: no stale-window carry-over
Reviews (2): Last reviewed commit: "chore(ci): remove stale release-as guard" | Re-trigger Greptile |
Drop the "Check for stale release-as pins" CI step and its companion "Test stale release-as guard" step from ci.yml, and delete .github/scripts/check-stale-release-as.js plus its node:test suite. The guard fails CI whenever a release-as pin equals its manifest version, which adds friction on every release for little value. The underlying advice -- do not leave an already-shipped release-as pin in place -- stays documented in CLAUDE.md as a manual check; it is simply no longer CI-enforced. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SDNQVLoAw4DbPrPvtQPobh Entire-Checkpoint: f4dca3728594
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #561 +/- ##
==========================================
+ Coverage 65.96% 70.01% +4.05%
==========================================
Files 149 177 +28
Lines 11503 21151 +9648
Branches 1305 1305
==========================================
+ Hits 7588 14809 +7221
- Misses 3673 6100 +2427
Partials 242 242
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Summary
Two small
chorecleanups, batched on this branch.1.
chore(api)— emit explicit zero for the IPNS-entries gauge on an empty tableMetricsService.collectGauges()callsthis.ipnsEntriesTotal.reset()then repopulatescipherbox_ipns_entries_totalfrom aGROUP BY record_typequery overfolder_ipns. When the table is empty that query returns zero rows, soreset()leaves the gauge with no series at all — Prometheus then serves the last non-zero sample through its staleness window and Grafana stat panels "stick" at it (a freshly-wiped environment mis-reporting as N IPNS entries; observed as a stale43after a staging reset).Fix: seed every known
record_type('folder','file') to0afterreset(), then overlay the real counts.users_total/files_totalalready behaved correctly because they always.set(0); this brings the label-partitioned IPNS gauge in line. Internal metrics only — no API surface change, no api-client regen.2.
chore(ci)— remove the stale release-as guardDrops the "Check for stale release-as pins" CI step and its companion "Test stale release-as guard" step from
ci.yml, and deletes.github/scripts/check-stale-release-as.js+ itsnode:testsuite. The guard failed CI whenever arelease-aspin equalled its manifest version, adding friction on every release for little value. The underlying advice (don't leave an already-shippedrelease-aspin in place) stays documented inCLAUDE.mdas a manual check — just no longer CI-enforced.Testing
metrics.service.spec.ts: added anipnsEntriesTotal gauge zero-state (regression)block — empty table →0for both types; partial population overlays real counts while absent types stay0. Full spec: 11 passed.eslintclean,tsc --noEmitclean on the API project.ci.yml/CLAUDE.mdpassprettier --check; YAML structure verified (lint job intact,typecheckjob follows).🤖 Generated with Claude Code