Skip to content

feat: alert on Raven when hourly backup success rate drops below 97% - #7382

Open
regdocs wants to merge 1 commit into
developfrom
backup-failure-rate-alert
Open

feat: alert on Raven when hourly backup success rate drops below 97%#7382
regdocs wants to merge 1 commit into
developfrom
backup-failure-rate-alert

Conversation

@regdocs

@regdocs regdocs commented Sep 4, 2026

Copy link
Copy Markdown
Member

Problem

Site backup failures are only visible one site at a time — a failure email to the affected team, plus the daily check_backup_records audit. Nothing surfaces a fleet-wide dip in the backup success rate while it's happening.

Solution

Add alert_if_backup_success_rate_is_low(), registered under hourly in hooks.py:

  • Counts Site Backups created in the last hour that have settled (Success / Failure). Pending and Running are excluded, since they haven't resolved yet.
  • If the success rate is below 97%, posts to the server alerts Raven channel. At or above the threshold it stays silent.
  • Returns early when the window has no completed backups, which also avoids a divide-by-zero.
  • The message follows the format of _send_public_server_pool_health_alert in server_monitoring.py: actual rate in the header, the threshold, totals, and a markdown table of the worst-offending sites (capped at 20, with a N more failures on other sites row when truncated).

It's two COUNT(*) queries in the common case, so it sits in hourly rather than hourly_long.

Notes for reviewers

Two calls worth a second opinion:

  • Channel — reuses RAVEN_SERVER_ALERTS_CHANNEL (frappe-cloud-server-alerts). Press Settings also has a raven_incidents_channel field if backup alerts belong there instead.
  • No minimum sample size — a quiet hour with 1 of 30 backups failing will trip the alert. Happy to add a floor if that turns out to be noisy.

Tests

TestBackupSuccessRateAlert covers below-threshold, exactly-at-threshold, an empty window, and unfinished backups not being counted.

🤖 Generated with Claude Code

Site backup failures were only visible per-site (failure emails to the
user, daily audit). Nothing flagged a fleet-wide dip in the backup
success rate.

Add an hourly check that compares settled Site Backups (Success/Failure)
created in the last hour against a 97% success-rate threshold, and posts
to the server alerts Raven channel when the rate falls below it. The
message lists the worst-offending sites, following the format used by
the public server pool health alert.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

Not safe to merge until delayed backup outcomes are included in the alert calculation.

The creation-time filter can permanently omit failures from long-running backups, defeating the alert during a realistic degraded state.

Files Needing Attention: press/press/doctype/site_backup/site_backup.py; press/press/doctype/site_backup/test_site_backup.py

Prompt To Fix All With AI
### Issue 1
press/press/doctype/site_backup/site_backup.py:960-962
**Delayed outcomes are omitted**
Backups receive their final status asynchronously, but this query filters them by creation time. A backup that takes more than an hour to settle is never counted, so delayed failures can be silently omitted from every alert.

### Issue 2
press/press/doctype/site_backup/test_site_backup.py:420-426
**Threshold boundary remains untested**
This test uses 34/35, which is 97.14%, rather than the exact 97% threshold. It would not catch a comparison regression at the boundary; use 97 successes and 3 failures instead.

```suggestion
	def test_no_alert_when_success_rate_is_at_threshold(self, mock_send_raven_message):
		# 97 out of 100 backups succeeded, i.e. 97%
		self._create_backups(successes=97, failures=3)

		alert_if_backup_success_rate_is_low()

		mock_send_raven_message.assert_not_called()
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat: alert on Raven when hourly backup ..." | Re-trigger Greptile

Comment on lines +960 to +962
completed_backups = frappe.db.count(
"Site Backup", {"status": ("in", ["Success", "Failure"]), "creation": (">=", since)}
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Delayed outcomes are omitted
Backups receive their final status asynchronously, but this query filters them by creation time. A backup that takes more than an hour to settle is never counted, so delayed failures can be silently omitted from every alert.

Knowledge Base Used: Database operations and backups

Prompt To Fix With AI
This is a comment left during a code review.
Path: press/press/doctype/site_backup/site_backup.py
Line: 960-962

Comment:
**Delayed outcomes are omitted**
Backups receive their final status asynchronously, but this query filters them by creation time. A backup that takes more than an hour to settle is never counted, so delayed failures can be silently omitted from every alert.

**Knowledge Base Used:** [Database operations and backups](https://app.greptile.com/frappe/-/custom-context/knowledge-base/frappe/press/-/docs/database-operations-and-backups.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +420 to +426
def test_no_alert_when_success_rate_is_at_threshold(self, mock_send_raven_message):
# 34 out of 35 backups succeeded, i.e. 97.14%
self._create_backups(successes=34, failures=1)

alert_if_backup_success_rate_is_low()

mock_send_raven_message.assert_not_called()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Threshold boundary remains untested
This test uses 34/35, which is 97.14%, rather than the exact 97% threshold. It would not catch a comparison regression at the boundary; use 97 successes and 3 failures instead.

Suggested change
def test_no_alert_when_success_rate_is_at_threshold(self, mock_send_raven_message):
# 34 out of 35 backups succeeded, i.e. 97.14%
self._create_backups(successes=34, failures=1)
alert_if_backup_success_rate_is_low()
mock_send_raven_message.assert_not_called()
def test_no_alert_when_success_rate_is_at_threshold(self, mock_send_raven_message):
# 97 out of 100 backups succeeded, i.e. 97%
self._create_backups(successes=97, failures=3)
alert_if_backup_success_rate_is_low()
mock_send_raven_message.assert_not_called()
Prompt To Fix With AI
This is a comment left during a code review.
Path: press/press/doctype/site_backup/test_site_backup.py
Line: 420-426

Comment:
**Threshold boundary remains untested**
This test uses 34/35, which is 97.14%, rather than the exact 97% threshold. It would not catch a comparison regression at the boundary; use 97 successes and 3 failures instead.

```suggestion
	def test_no_alert_when_success_rate_is_at_threshold(self, mock_send_raven_message):
		# 97 out of 100 backups succeeded, i.e. 97%
		self._create_backups(successes=97, failures=3)

		alert_if_backup_success_rate_is_low()

		mock_send_raven_message.assert_not_called()
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codecov-commenter

codecov-commenter commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.18182% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 61.05%. Comparing base (59dc872) to head (c210dda).
⚠️ Report is 8 commits behind head on develop.

Files with missing lines Patch % Lines
press/press/doctype/site_backup/site_backup.py 95.45% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           develop    #7382       +/-   ##
============================================
- Coverage    85.83%   61.05%   -24.79%     
============================================
  Files          137     1059      +922     
  Lines        26237   100134    +73897     
  Branches      1643     1643               
============================================
+ Hits         22521    61138    +38617     
- Misses        3675    38956    +35281     
+ Partials        41       40        -1     
Flag Coverage Δ
dashboard 85.84% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mergify

mergify Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

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.

2 participants