Files
karma/internal/models/alertgroup.go
2018-09-09 14:12:26 +01:00

76 lines
2.2 KiB
Go

package models
import (
"crypto/sha1"
"fmt"
"io"
"github.com/cnf/structhash"
log "github.com/sirupsen/logrus"
)
// AlertList is flat list of karmaAlert objects
type AlertList []Alert
func (a AlertList) Len() int {
return len(a)
}
func (a AlertList) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a AlertList) Less(i, j int) bool {
// compare timestamps, if equal compare fingerprints to stable sort order
if a[i].StartsAt.After(a[j].StartsAt) {
return true
}
if a[i].StartsAt.Before(a[j].StartsAt) {
return false
}
return a[i].LabelsFingerprint() < a[j].LabelsFingerprint()
}
// AlertGroup is vanilla Alertmanager group, but alerts are flattened
// There is a hash computed from all alerts, it's used by UI to quickly tell
// if there was any change in a group and it needs to refresh it
type AlertGroup struct {
Receiver string `json:"receiver"`
Labels map[string]string `json:"labels"`
Alerts AlertList `json:"alerts"`
ID string `json:"id"`
Hash string `json:"hash"`
AlertmanagerCount map[string]int `json:"alertmanagerCount"`
StateCount map[string]int `json:"stateCount"`
}
// LabelsFingerprint is a checksum of this AlertGroup labels and the receiver
// it should be unique for each AlertGroup
func (ag AlertGroup) LabelsFingerprint() string {
agIDHasher := sha1.New()
_, err := io.WriteString(agIDHasher, ag.Receiver)
if err != nil {
log.Errorf("Failed to write receiver value to alertgroup '%s' fingerprint: %s", ag.ID, err)
}
_, err = io.WriteString(agIDHasher, fmt.Sprintf("%x", structhash.Sha1(ag.Labels, 1)))
if err != nil {
log.Errorf("Failed to write labels sha1 value to alertgroup '%s' fingerprint: %s", ag.ID, err)
}
return fmt.Sprintf("%x", agIDHasher.Sum(nil))
}
// ContentFingerprint is a checksum of all alerts in the group
func (ag AlertGroup) ContentFingerprint() string {
h := sha1.New()
for _, alert := range ag.Alerts {
_, err := io.WriteString(h, alert.ContentFingerprint())
if err != nil {
log.Errorf("Failed to write alert fingerprint value to alertgroup '%s' fingerprint: %s", ag.ID, err)
}
}
return fmt.Sprintf("%x", h.Sum(nil))
}