Alerting: Remove empty/namespace labels when sending alerts to the remote Alertmanager (#90284)

* Alerting: Remove empty/namespace labels when sending alerts to the remote Alertmanager

* update tests

* fix typo in comment
This commit is contained in:
Santiago 2024-07-11 15:20:12 +02:00 committed by GitHub
parent c1d9e793be
commit 3bb861b9f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 3 deletions

View File

@ -19,6 +19,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
alertingClusterPB "github.com/grafana/alerting/cluster/clusterpb"
alertingModels "github.com/grafana/alerting/models"
alertingNotify "github.com/grafana/alerting/notify"
"gopkg.in/yaml.v3"
@ -467,6 +468,16 @@ func (am *Alertmanager) GetAlertGroups(ctx context.Context, active, silenced, in
}
func (am *Alertmanager) PutAlerts(ctx context.Context, alerts apimodels.PostableAlerts) error {
for _, a := range alerts.PostableAlerts {
for k, v := range a.Labels {
// The Grafana Alertmanager skips empty and namespace UID labels.
// To get the same alert fingerprint we need to remove these labels too.
// https://github.com/grafana/alerting/blob/2dda1c67ec02625ac9fc8607157b3d5825d47919/notify/grafana_alertmanager.go#L722-L724
if len(v) == 0 || k == alertingModels.NamespaceUIDLabel {
delete(a.Labels, k)
}
}
}
am.log.Debug("Sending alerts to a remote alertmanager", "url", am.url, "alerts", len(alerts.PostableAlerts))
am.sender.SendAlerts(alerts)
return nil

View File

@ -21,6 +21,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/alerting/definition"
alertingModels "github.com/grafana/alerting/models"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
@ -668,9 +669,9 @@ func TestIntegrationRemoteAlertmanagerAlerts(t *testing.T) {
require.Equal(t, 0, len(alertGroups))
// Let's create two active alerts and one expired one.
alert1 := genAlert(true, map[string]string{"test_1": "test_1"})
alert2 := genAlert(true, map[string]string{"test_2": "test_2"})
alert3 := genAlert(false, map[string]string{"test_3": "test_3"})
alert1 := genAlert(true, map[string]string{"test_1": "test_1", "empty": "", alertingModels.NamespaceUIDLabel: "test_1"})
alert2 := genAlert(true, map[string]string{"test_2": "test_2", "empty": "", alertingModels.NamespaceUIDLabel: "test_2"})
alert3 := genAlert(false, map[string]string{"test_3": "test_3", "empty": "", alertingModels.NamespaceUIDLabel: "test_3"})
postableAlerts := apimodels.PostableAlerts{
PostableAlerts: []amv2.PostableAlert{alert1, alert2, alert3},
}
@ -688,6 +689,12 @@ func TestIntegrationRemoteAlertmanagerAlerts(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 1, len(alertGroups))
// Labels with empty values and the namespace UID label should be removed.
for _, a := range alertGroups {
require.NotContains(t, a.Labels, "empty")
require.NotContains(t, a.Labels, alertingModels.NamespaceUIDLabel)
}
// Filtering by `test_1=test_1` should return one alert.
alerts, err = am.GetAlerts(context.Background(), true, true, true, []string{"test_1=test_1"}, "")
require.NoError(t, err)