Is the fingerprint field in Alertmanager unique?
Asked Answered
W

1

7

I am developing a dashboard, which receives all Alertmanager readings and processes them. I looked for a unique field in the request payload to create a unique external alert id in my database. The request payload looks something like this:

{
  "status": "firing",
  "labels": {
    "alertname": "",
    "app": "",
    "cluster": "",
    "deployed_location": "",
    "instance": "",
    "job": "",
    "kubernetes_namespace": "",
    "kubernetes_pod_name": "",
    "pod_template_hash": "",
    "release": "",
    "replica": "",
    "severity": ""
  },
  "annotations": {
    "description": "",
    "summary": ""
  },
  "startsAt": "",
  "endsAt": "",
  "generatorURL": "",
  "fingerprint": ""
}

I first used the generatorURL field, but then realized it many different alerts have the same value for generatorURL. I have been trying fingerprint, and the situation is much better. However, I am having instances where 2 to 15 alerts have the same fingerprint.

I am wondering:

  1. Is there really no unique field in Alertmanager requests?
  2. It is the nature of Alertmanager logic (or that of my alerts) that a number of alerts are created with the same fingerprint and I should just deal with it and handle it on my side, i.e. not create an incident in my DB if the given fingerprint is already used. I also worry that if I set unique=True on my alert model, some new alerts that have the same fingerprint will be missed...
William answered 27/11, 2019 at 9:6 Comment(1)
At this point, I am pretty sure the fingerprint field is NOT unique. What's more interesting, though, is that I'm using fingerprint, alertName, and startsAt to generate a unique id, and I am still getting duplicate alerts.William
G
9

If you jump to the alert.Fingerprint() definition, like this one, can find the impl of fingerprint

So, alert.Fingerprint() is just unique for labels

// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as
// parameter (rather than a label map) and returns a Fingerprint.
func labelSetToFingerprint(ls LabelSet) Fingerprint {
    if len(ls) == 0 {
        return Fingerprint(emptyLabelSignature)
    }

    labelNames := make(LabelNames, 0, len(ls))
    for labelName := range ls {
        labelNames = append(labelNames, labelName)
    }
    sort.Sort(labelNames)

    sum := hashNew()
    for _, labelName := range labelNames {
        sum = hashAdd(sum, string(labelName))
        sum = hashAddByte(sum, SeparatorByte)
        sum = hashAdd(sum, string(ls[labelName]))
        sum = hashAddByte(sum, SeparatorByte)
    }
    return Fingerprint(sum)
}
Garrard answered 2/10, 2020 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.