diff --git a/notifier/notifier.go b/notifier/notifier.go index 2e36b62b7..a577e027e 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -211,6 +211,15 @@ func (n *Notifier) Send(alerts ...*model.Alert) { n.mtx.Lock() defer n.mtx.Unlock() + // Attach external labels before relabelling and sending. + for _, a := range alerts { + for ln, lv := range n.opts.ExternalLabels { + if _, ok := a.Labels[ln]; !ok { + a.Labels[ln] = lv + } + } + } + alerts = n.relabelAlerts(alerts) // Queue capacity should be significantly larger than a single alert @@ -267,15 +276,6 @@ func postURL(u string) string { func (n *Notifier) sendAll(alerts ...*model.Alert) int { begin := time.Now() - // Attach external labels before sending alerts. - for _, a := range alerts { - for ln, lv := range n.opts.ExternalLabels { - if _, ok := a.Labels[ln]; !ok { - a.Labels[ln] = lv - } - } - } - b, err := json.Marshal(alerts) if err != nil { log.Errorf("Encoding alerts failed: %s", err) diff --git a/notifier/notifier_test.go b/notifier/notifier_test.go index 1d876e50a..efe248a9e 100644 --- a/notifier/notifier_test.go +++ b/notifier/notifier_test.go @@ -153,7 +153,6 @@ func TestHandlerSendAll(t *testing.T) { h := New(&Options{ AlertmanagerURLs: []string{server1.URL, server2.URL}, Timeout: time.Minute, - ExternalLabels: model.LabelSet{"a": "b"}, }) for i := range make([]struct{}, maxBatchSize) { @@ -165,7 +164,6 @@ func TestHandlerSendAll(t *testing.T) { expected = append(expected, &model.Alert{ Labels: model.LabelSet{ "alertname": model.LabelValue(fmt.Sprintf("%d", i)), - "a": "b", }, }) } @@ -187,6 +185,56 @@ func TestHandlerSendAll(t *testing.T) { } } +func TestExternalLabels(t *testing.T) { + h := New(&Options{ + QueueCapacity: 3 * maxBatchSize, + ExternalLabels: model.LabelSet{"a": "b"}, + RelabelConfigs: []*config.RelabelConfig{ + { + SourceLabels: model.LabelNames{"alertname"}, + TargetLabel: "a", + Action: "replace", + Regex: config.MustNewRegexp("externalrelabelthis"), + Replacement: "c", + }, + }, + }) + + // This alert should get the external label attached. + h.Send(&model.Alert{ + Labels: model.LabelSet{ + "alertname": "test", + }, + }) + + // This alert should get the external label attached, but then set to "c" + // through relabelling. + h.Send(&model.Alert{ + Labels: model.LabelSet{ + "alertname": "externalrelabelthis", + }, + }) + + expected := []*model.Alert{ + { + Labels: model.LabelSet{ + "alertname": "test", + "a": "b", + }, + }, + { + Labels: model.LabelSet{ + "alertname": "externalrelabelthis", + "a": "c", + }, + }, + } + + if !alertsEqual(expected, h.queue) { + t.Errorf("Expected alerts %v, got %v", expected, h.queue) + } +} + func TestHandlerRelabel(t *testing.T) { h := New(&Options{ QueueCapacity: 3 * maxBatchSize,