diff --git a/app/vmalert/alerting.go b/app/vmalert/alerting.go index 67259c792..cafa5a0d3 100644 --- a/app/vmalert/alerting.go +++ b/app/vmalert/alerting.go @@ -153,6 +153,13 @@ func (ar *AlertingRule) ExecRange(ctx context.Context, start, end time.Time) ([] return nil, fmt.Errorf("`query` template isn't supported in replay mode") } for _, s := range series { + // set additional labels to identify group and rule name + if ar.Name != "" { + s.SetLabel(alertNameLabel, ar.Name) + } + if !*disableAlertGroupLabel && ar.GroupName != "" { + s.SetLabel(alertGroupNameLabel, ar.GroupName) + } // extra labels could contain templates, so we expand them first labels, err := expandLabels(s, qFn, ar) if err != nil { @@ -163,13 +170,6 @@ func (ar *AlertingRule) ExecRange(ctx context.Context, start, end time.Time) ([] // so the hash key will be consistent on restore s.SetLabel(k, v) } - // set additional labels to identify group and rule name - if ar.Name != "" { - s.SetLabel(alertNameLabel, ar.Name) - } - if !*disableAlertGroupLabel && ar.GroupName != "" { - s.SetLabel(alertGroupNameLabel, ar.GroupName) - } a, err := ar.newAlert(s, time.Time{}, qFn) // initial alert if err != nil { return nil, fmt.Errorf("failed to create alert: %s", err) @@ -225,6 +225,13 @@ func (ar *AlertingRule) Exec(ctx context.Context) ([]prompbmarshal.TimeSeries, e updated := make(map[uint64]struct{}) // update list of active alerts for _, m := range qMetrics { + // set additional labels to identify group and rule name + if ar.Name != "" { + m.SetLabel(alertNameLabel, ar.Name) + } + if !*disableAlertGroupLabel && ar.GroupName != "" { + m.SetLabel(alertGroupNameLabel, ar.GroupName) + } // extra labels could contain templates, so we expand them first labels, err := expandLabels(m, qFn, ar) if err != nil { @@ -235,14 +242,6 @@ func (ar *AlertingRule) Exec(ctx context.Context) ([]prompbmarshal.TimeSeries, e // so the hash key will be consistent on restore m.SetLabel(k, v) } - // set additional labels to identify group and rule name - // set additional labels to identify group and rule name - if ar.Name != "" { - m.SetLabel(alertNameLabel, ar.Name) - } - if !*disableAlertGroupLabel && ar.GroupName != "" { - m.SetLabel(alertGroupNameLabel, ar.GroupName) - } h := hash(m) if _, ok := updated[h]; ok { // duplicate may be caused by extra labels diff --git a/app/vmalert/alerting_test.go b/app/vmalert/alerting_test.go index cff88f53b..c72daa213 100644 --- a/app/vmalert/alerting_test.go +++ b/app/vmalert/alerting_test.go @@ -715,6 +715,44 @@ func TestAlertingRule_Template(t *testing.T) { }, }, }, + { + &AlertingRule{ + Name: "ExtraTemplating", + GroupName: "Testing", + Labels: map[string]string{ + "name": "alert_{{ $labels.alertname }}", + "group": "group_{{ $labels.alertgroup }}", + "instance": "{{ $labels.instance }}", + }, + Annotations: map[string]string{ + "summary": `Alert "{{ $labels.alertname }}({{ $labels.alertgroup }})" for instance {{ $labels.instance }}`, + "description": `Alert "{{ $labels.name }}({{ $labels.group }})" for instance {{ $labels.instance }}`, + }, + alerts: make(map[uint64]*notifier.Alert), + }, + []datasource.Metric{ + metricWithValueAndLabels(t, 1, "instance", "foo"), + }, + map[uint64]*notifier.Alert{ + hash(metricWithLabels(t, alertNameLabel, "ExtraTemplating", + "name", "alert_ExtraTemplating", + alertGroupNameLabel, "Testing", + "group", "group_Testing", + "instance", "foo")): { + Labels: map[string]string{ + alertNameLabel: "ExtraTemplating", + "name": "alert_ExtraTemplating", + alertGroupNameLabel: "Testing", + "group": "group_Testing", + "instance": "foo", + }, + Annotations: map[string]string{ + "summary": `Alert "ExtraTemplating(Testing)" for instance foo`, + "description": `Alert "alert_ExtraTemplating(group_Testing)" for instance foo`, + }, + }, + }, + }, } fakeGroup := Group{Name: "TestRule_Exec"} for _, tc := range testCases {