fix(selfhost): alert explicitly when the monitored D1 approaches its 10 GB cap - #9458
Conversation
…10 GB cap The D1 size probe (#3810) sampled file_size into a /metrics gauge and stopped there — an operator with no scrape/dashboard stack got nothing as the database climbed toward its cap, and the cap is an outage, not a degradation: at 10 GB every write fails with `D1_ERROR: Exceeded maximum DB size`, including the webhook relay's own INSERT, so inbound delivery stops fleet-wide (observed 2026-07-06 and again 2026-07-26). Turn the same sample into an explicit structured console.error plus a PostHog capture at 70% (warn — ~3 GB headroom) and 85% (critical — headroom is weeks at the measured write rate), latched per level so an alert fires on crossing rather than every probe tick, with hysteresis: dropping back below a threshold logs a recovery line and re-arms it. A failed size fetch (carried-forward sample) never fires or recovers the latch. Closes #9435
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-27 20:22:38 UTC
Review summary Nits — 6 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
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://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Decision record
🟩 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.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9458 +/- ##
==========================================
+ Coverage 89.54% 93.62% +4.07%
==========================================
Files 843 741 -102
Lines 110011 60373 -49638
Branches 26184 21291 -4893
==========================================
- Hits 98511 56522 -41989
+ Misses 10238 2900 -7338
+ Partials 1262 951 -311
Flags with carried forward coverage won't be shown. Click here to find out more.
|
…FAULT_METRIC_META The metric-meta drift guard (selfhost-metrics.test.ts) correctly failed on the new counter having no registered help/type entry.
…orking tree b4bba03's git add -A picked up an uncommitted src/config/loopover-repo-focus-manifest.ts edit that belonged to the (since-merged) screenshot-gate branch, without its .loopover.yml counterpart — tripping the manifest drift check on a PR that never meant to touch either file. Restore the file to this branch's base; the gate block lands via main where both sides changed together.
Problem
#9435: the D1 that backs the hosted deployment filled to its 10 GB cap twice (2026-07-06, 2026-07-26). At the cap every write fails — including the webhook relay's INSERT — so inbound webhook delivery stops fleet-wide. Both times the first signal was the outage itself.
The size probe (#3810,
d1-size-probe.ts) already samplesfile_sizevia the Cloudflare Management API — but only into a/metricsgauge. With no scrape/dashboard stack watching that endpoint, the reading existed and alerted no one: the same config-dependent-observability-ships-inert failure mode #9433 tracks.Change
checkD1SizeThreshold, fed by each fresh probe sample:On crossing a level: one structured
console.error(event: "d1_size_threshold"), aloopover_d1_size_threshold_alerts_total{level}counter tick, and a PostHog exception capture (d1_size_threshold) — surfaces the operator already watches, no metrics stack required.Latched per level with hysteresis: an alert fires on crossing, never per tick; dropping back below logs an info-grade recovery line and re-arms the latch; a later re-crossing fires again. A failed size fetch (the probe's carried-forward sample) neither fires nor recovers the latch.
Tests
All six behaviors pinned: silent below warn, single fire + capture at warn, warn→critical escalation without intra-level re-fire, recovery + re-arm, critical→warn downgrade without alert, and the probe-integration case (fresh reading alerts; failed fetch doesn't).
d1-size-probe.tsis at 100% statements and branches.Closes #9435