Repository: prometheus/alertmanager
File: notify/notify.go (Go)

Code before:
	case ReasonNewResolvedAlerts:
		return "some alerts resolved"
	case ReasonAllAlertsResolved:
		return "all alerts resolved"
	case ReasonRepeatIntervalElapsed:
		return "repeat interval elapsed"
	default:
		return "unknown"
	}
}

func (n *DedupStage) needsUpdate(entry *nflogpb.Entry, firing, resolved map[uint64]struct{}, repeat time.Duration) NotifyReason {
	// If we haven't notified about the alert group before, notify right away
	// unless we only have resolved alerts.
	if entry == nil {
		newAlerts := len(firing) > 0
		if newAlerts {
			return ReasonFirstNotification
		}
		return ReasonDoNotNotify
	}

	// new alerts in the group
	if !entry.IsFiringSubset(firing) {
		// If the previous entry has no firing alerts, it was a reason and we
		// should treat thisas the first notification for the group.
		if len(entry.FiringAlerts) == 0 {
			return ReasonFirstNotification
		}
		return ReasonNewAlertsInGroup
	}

	// Notify about all alerts being resolved.
	// This is done irrespective of the send_resolved flag to make sure that
	// the firing alerts are cleared from the notification log.
	if len(firing) == 0 {
		// If the current alert group and last notification contain no firing
		// alert, it means that some alerts have been fired and resolved during the
		// last interval. In this case, there is no need to notify the receiver
		// since it doesn't know about them.
		if len(entry.FiringAlerts) > 0 {
			return ReasonAllAlertsResolved
		}
		return ReasonDoNotNotify
	}

	if n.rs.SendResolved() && !entry.IsResolvedSubset(resolved) {
		return ReasonNewResolvedAlerts
	}

	// Nothing changed, only notify if the repeat interval has passed.

Review comment (suggestion):
```suggestion
		// should treat this as the first notification for the group.
```

Code after:
	case ReasonNewResolvedAlerts:
		return "some alerts resolved"
	case ReasonAllAlertsResolved:
		return "all alerts resolved"
	case ReasonRepeatIntervalElapsed:
		return "repeat interval elapsed"
	default:
		return "unknown"
	}
}

func (n *DedupStage) needsUpdate(entry *nflogpb.Entry, firing, resolved map[uint64]struct{}, repeat time.Duration) NotifyReason {
	// If we haven't notified about the alert group before, notify right away
	// unless we only have resolved alerts.
	if entry == nil {
		if len(firing) > 0 {
			return ReasonFirstNotification
		}
		return ReasonDoNotNotify
	}

	// new alerts in the group
	if !entry.IsFiringSubset(firing) {
		// If the previous entry has no firing alerts, it was a resolution and we
		// should treat this as the first notification for the group.
		if len(entry.FiringAlerts) == 0 {
			return ReasonFirstNotification
		}
		return ReasonNewAlertsInGroup
	}

	// Notify about all alerts being resolved.
	// This is done irrespective of the send_resolved flag to make sure that
	// the firing alerts are cleared from the notification log.
	if len(firing) == 0 {
		// If the current alert group and last notification contain no firing
		// alert, it means that some alerts have been fired and resolved during the
		// last interval. In this case, there is no need to notify the receiver
		// since it doesn't know about them.
		if len(entry.FiringAlerts) > 0 {
			return ReasonAllAlertsResolved
		}
		return ReasonDoNotNotify
	}

	if n.rs.SendResolved() && !entry.IsResolvedSubset(resolved) {
		return ReasonNewResolvedAlerts
	}

	// Nothing changed, only notify if the repeat interval has passed.
	isRepeatIntervalElapsed := entry.Timestamp.Before(n.now().Add(-repeat))