Skip to content

Alert when the daily workspace backup sweep does not run - #839

Merged
InfinityBowman merged 1 commit into
mainfrom
infra/backup-sweep-alerts
Sep 19, 2026
Merged

InfinityBowman merged 1 commit into
mainfrom
infra/backup-sweep-alerts

Conversation

@InfinityBowman

@InfinityBowman InfinityBowman commented Sep 18, 2026

Copy link
Copy Markdown
Owner

The backup sweep from #827 leaves exactly one trace per day: a single backup.completed log line. Nothing watches for its absence, so a cron that silently stops firing is indistinguishable from a healthy quiet day. Verifying that last night's backup actually happened meant listing R2 objects by hand and summing their sizes against the logged byte count.

Rules

New backups group in config/grafana/provisioning/alerting/backups.yaml, following the shape of invitations.yaml.

Rule Fires on Severity
Daily workspace backup did not run no backup.completed in 26h critical
A project was skipped by the backup sweep any backup.failed, grouped by stage and projectId critical

The 26h window gives the 05:00 UTC cron a 2h grace period, which also absorbs Cloudflare re-delivering OTLP batches hours late.

The second rule covers both failure stages the sweep emits: stage=sweep means a project has no snapshot for that day, stage=pre-delete means a project was torn down without its final deleted/ copy, which nothing retries.

One inversion worth reviewing

Everywhere else in alerting/, a trailing or vector(0) exists to keep a Normal series alive so that No Data means Loki is broken rather than "nothing failed". On the absence rule it does the opposite: an empty result evaluates to 0 and trips the lt 1 threshold. noDataState is Alerting for the same reason. A rule that cannot confirm a backup happened should fire, not stay quiet. Both the file header and the README call this out so it does not read as a copy-paste slip.

Verification

All three LogQL expressions were run against production Loki before the file was written: the absence query returns 1 (today's sweep), both failure queries return 0.

Already deployed to the homelab Grafana: deploy.sh to rsync the config, then a corates-grafana restart, since compose alone will not reload bind-mounted provisioning. Grafana logged finished to provision alerting with no errors and /api/v1/provisioning/alert-rules lists both UIDs. Merging this only brings the repo in line with what is already running.

While checking the sweep's history I confirmed backups themselves are healthy: both runs since #827 landed (Sept 17, 8/8; Sept 18, 9/9), every object exists in corates-backups-prod, and the sizes sum byte for byte to the logged totals. The two zero-row snapshots are genuinely empty workspaces, cross-checked against the live DOs via sync-admin stats.

Not covered here

A project created after the sweep has no backup until the next midnight. Today that was a real project that took a full day of two-reviewer work in its first 19 hours. Fixing it means a second daily sweep or a snapshot on project create, which is a change to the worker rather than to alerting.

https://claude.ai/code/session_01JySapHzgzwPW1yBWHccZYf

Summary by CodeRabbit

  • New Features

    • Added monitoring alerts for the daily workspace backup process.
    • Alerts now flag missing backup completion activity and failed backups, including the affected project and stage where available.
    • Alerts use a 15-minute evaluation window and critical severity to support timely investigation.
  • Documentation

    • Added guidance describing backup alert conditions, timing, and expected behavior.

The sweep's only trace is one log line, so a cron that silently stops
producing nothing looked exactly like a healthy quiet day. Confirming a
backup happened meant counting objects in R2 by hand.

Two provisioned rules in a new backups group:

- no backup.completed in 26h (2h grace on the 05:00 UTC cron, which also
  absorbs Cloudflare re-delivering OTLP batches late)
- any backup.failed, grouped by stage and projectId so the notification
  names the project

The absence rule inverts the file-level `or vector(0)` convention: an
empty result evaluates to 0 and trips the threshold instead of holding a
Normal series, and noDataState is Alerting for the same reason. If the
rule cannot confirm a backup ran, it should fire.

Claude-Session: https://claude.ai/code/session_01JySapHzgzwPW1yBWHccZYf
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: ca7bcbbd-36f4-45eb-99c7-16f756e266a6

📥 Commits

Reviewing files that changed from the base of the PR and between 2a70a4a and 82ed19a.

📒 Files selected for processing (2)
  • infra/observability/README.md
  • infra/observability/config/grafana/provisioning/alerting/backups.yaml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
NEVER use emojis anywhere - not in code, comments, documentation, plan files, commit messages, or examples.

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Files:

  • infra/observability/README.md
  • infra/observability/config/grafana/provisioning/alerting/backups.yaml
🔇 Additional comments (2)
infra/observability/config/grafana/provisioning/alerting/backups.yaml (1)

1-87: LGTM!

infra/observability/README.md (1)

210-218: LGTM!


📝 Walkthrough

Walkthrough

Grafana provisioning adds alerts for missing workspace backup completions and failed backup events. The observability README documents the alert group, queries, thresholds, grouping, and no-data behavior.

Changes

Backup alerting

Layer / File(s) Summary
Missing backup sweep alert
infra/observability/config/grafana/provisioning/alerting/backups.yaml
Adds the backups alert group and a rule that checks for backup.completed events within 26 hours. The rule alerts when the count is below one and treats no data as alerting.
Failed backup project alert
infra/observability/config/grafana/provisioning/alerting/backups.yaml, infra/observability/README.md
Adds a rule that detects backup.failed events grouped by stage and projectId. The README documents both rules and their evaluation behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to 82ed1

The backup alerts correctly detect missing completed sweeps and per-project backup failures. No merge-blocking risk is identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: alerting when the daily workspace backup sweep does not run. It is concise and specific, although it does not mention the separate failure-event alert.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@InfinityBowman
InfinityBowman merged commit 3d31d73 into main Sep 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant