Skip to content

Commit 13845e5

Browse files
tennislengAndrew Leng
authored andcommitted
fix: update endsAt when resolving alerts via API
When an alert is posted via the API with only endsAt set (to resolve an existing alert), the endsAt field was not being updated due to two issues: 1. The merge condition in provider/mem/mem.go only merged alerts when there was an overlap in activity range. This prevented merging when resolving an alert (where the new endsAt is before the old endsAt timeout). 2. The Merge function in types/types.go didn't properly handle the case where a new resolved alert is merged with an existing unresolved alert. This fix: - Updates the merge condition to also merge when updating an existing alert (same fingerprint), allowing updates like setting endsAt to resolve an alert even without overlap. - Updates the Merge function to always use the new alert's EndsAt when it is resolved, ensuring that resolving an alert via API properly updates the endsAt timestamp. Fixes #4554 Signed-off-by: tennisleng <tennisleng@users.noreply.github.com>
1 parent 45554d1 commit 13845e5

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

provider/mem/mem.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,17 @@ func (a *Alerts) Put(alerts ...*types.Alert) error {
242242
if old, err := a.alerts.Get(fp); err == nil {
243243
existing = true
244244

245-
// Merge alerts if there is an overlap in activity range.
246-
if (alert.EndsAt.After(old.StartsAt) && alert.EndsAt.Before(old.EndsAt)) ||
247-
(alert.StartsAt.After(old.StartsAt) && alert.StartsAt.Before(old.EndsAt)) {
245+
// Merge alerts if there is an overlap in activity range, or if
246+
// the new alert is updating the existing alert (e.g., setting endsAt
247+
// to resolve it, or updating annotations/labels).
248+
hasOverlap := (alert.EndsAt.After(old.StartsAt) && alert.EndsAt.Before(old.EndsAt)) ||
249+
(alert.StartsAt.After(old.StartsAt) && alert.StartsAt.Before(old.EndsAt))
250+
251+
// Also merge if updating an existing alert (same fingerprint) to allow
252+
// updates like setting endsAt to resolve an alert, even without overlap.
253+
isUpdate := !alert.UpdatedAt.Before(old.UpdatedAt)
254+
255+
if hasOverlap || isUpdate {
248256
alert = old.Merge(alert)
249257
}
250258
}

types/types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,9 @@ func (a *Alert) Merge(o *Alert) *Alert {
453453
}
454454

455455
if o.Resolved() {
456+
// If the new alert is resolved, use its EndsAt timestamp.
457+
// This handles the case where an alert is being resolved via API.
458+
res.EndsAt = o.EndsAt
456459
// The latest explicit resolved timestamp wins if both alerts are effectively resolved.
457460
if a.Resolved() && a.EndsAt.After(o.EndsAt) {
458461
res.EndsAt = a.EndsAt

0 commit comments

Comments
 (0)