Show notes from similar earlier incidents
Each incident gets a signature: the alert name plus the group labels that
say what is broken, minus the ones that only say where it ran (instance,
pod, container, ...). GET /api/incidents/{id}/similar returns resolved
incidents in the same team with the same signature that have notes.
Notes can be marked as the resolution note, "what fixed it", either with a
resolution field on resolve or pinned on a note. Those lead the similar
list, show on the incident page as "Seen before", and the triggered
notification carries the latest one.
Claude-Session: https://claude.ai/code/session_01MMados3BD1oSjevHxbmVqU
This commit is contained in:
@@ -36,6 +36,10 @@ const (
|
||||
evUnsnoozed = "unsnoozed"
|
||||
evResolved = "resolved"
|
||||
evNote = "note"
|
||||
// evResolutionNote is the note worth finding again: what fixed it. The
|
||||
// similar-incidents lookup and the page lead with these; plain notes are
|
||||
// the working chatter and stay one click away.
|
||||
evResolutionNote = "resolution_note"
|
||||
evDeadmanSilent = "deadman_silent"
|
||||
)
|
||||
|
||||
@@ -295,6 +299,34 @@ func openIncidentForAlert(ctx context.Context, q querier, alertID int64) (int64,
|
||||
return id, err
|
||||
}
|
||||
|
||||
// volatileLabels say where a problem ran this time, not what the problem is, so
|
||||
// they stay out of the signature. Migration 008's backfill lists the same set.
|
||||
var volatileLabels = map[string]bool{
|
||||
"instance": true, "pod": true, "pod_name": true, "pod_ip": true,
|
||||
"container": true, "container_name": true, "endpoint": true,
|
||||
}
|
||||
|
||||
// incidentSignature identifies "the same problem" across incidents: the alert
|
||||
// name plus the stable group labels, sorted. Incidents in one team with equal
|
||||
// signatures are what the similar-incidents lookup returns. title stands in for
|
||||
// the name when the payload carried no alertname (groupless and dead man's
|
||||
// switch incidents).
|
||||
func incidentSignature(groupLabels map[string]string, title string) string {
|
||||
name := groupLabels["alertname"]
|
||||
if name == "" {
|
||||
name = title
|
||||
}
|
||||
rest := make([]string, 0, len(groupLabels))
|
||||
for k, v := range groupLabels {
|
||||
if k == "alertname" || volatileLabels[k] {
|
||||
continue
|
||||
}
|
||||
rest = append(rest, k+"="+v)
|
||||
}
|
||||
sort.Strings(rest)
|
||||
return name + "|" + strings.Join(rest, ",")
|
||||
}
|
||||
|
||||
// incidentTitle renders a human-readable title from Alertmanager's groupLabels,
|
||||
// leading with the alert name and appending whatever else the operator grouped
|
||||
// by. Falls back to the alert's own name when the payload carried no groupLabels.
|
||||
|
||||
Reference in New Issue
Block a user