fix: respect quiet hours for recovery notifications (#1068)

Recovery notifications were bypassing the quiet hours check, causing
users to receive recovery alerts during their configured quiet hours
window even though the original "down" alerts were suppressed.

- Add ShouldSuppressResolvedNotification() to alert manager
- Check quiet hours before sending recovery notifications in monitor
- Recovery notifications now follow same suppression rules as alerts
This commit is contained in:
rcourtman 2026-01-09 21:47:36 +00:00
parent 2a8f55d719
commit 07b4765b8d
2 changed files with 27 additions and 0 deletions

View file

@ -2116,6 +2116,29 @@ func (m *Manager) shouldSuppressNotification(alert *Alert) (bool, string) {
return false, ""
}
// ShouldSuppressResolvedNotification checks if a recovery notification should be suppressed
// during quiet hours. Recovery notifications follow the same quiet hours rules as their
// corresponding alerts - if the original alert would have been suppressed, so is the recovery.
func (m *Manager) ShouldSuppressResolvedNotification(alert *Alert) bool {
if alert == nil {
return false
}
m.mu.RLock()
defer m.mu.RUnlock()
suppressed, reason := m.shouldSuppressNotification(alert)
if suppressed {
log.Debug().
Str("alertID", alert.ID).
Str("type", alert.Type).
Str("level", string(alert.Level)).
Str("quietHoursRule", reason).
Msg("Recovery notification suppressed during quiet hours")
}
return suppressed
}
// shouldNotifyAfterCooldown checks if enough time has passed since the last notification
// Returns true if notification should be sent, false if still in cooldown period
func (m *Manager) shouldNotifyAfterCooldown(alert *Alert) bool {

View file

@ -8131,6 +8131,10 @@ func (m *Monitor) handleAlertResolved(alertID string) {
m.notificationMgr.CancelAlert(alertID)
if m.notificationMgr.GetNotifyOnResolve() {
if resolved := m.alertManager.GetResolvedAlert(alertID); resolved != nil {
// Check if recovery notification should be suppressed during quiet hours
if m.alertManager.ShouldSuppressResolvedNotification(resolved.Alert) {
return
}
go m.notificationMgr.SendResolvedAlert(resolved)
}
}