mirror of
https://github.com/prymitive/karma
synced 2026-05-19 04:26:41 +00:00
fix(api): use slices for labels instead of maps
This commit is contained in:
committed by
Łukasz Mierzwa
parent
7d24a7ece0
commit
8f7cca40cc
@@ -141,14 +141,14 @@ func resolveLabelValue(name, value string) string {
|
||||
}
|
||||
|
||||
func getGroupLabel(group *models.APIAlertGroup, label string) string {
|
||||
if v, found := group.Labels[label]; found {
|
||||
return resolveLabelValue(label, v)
|
||||
if v := group.Labels.Get(label); v != nil {
|
||||
return resolveLabelValue(label, v.Value)
|
||||
}
|
||||
if v, found := group.Shared.Labels[label]; found {
|
||||
return resolveLabelValue(label, v)
|
||||
if v := group.Shared.Labels.Get(label); v != nil {
|
||||
return resolveLabelValue(label, v.Value)
|
||||
}
|
||||
if v, found := group.Alerts[0].Labels[label]; found {
|
||||
return resolveLabelValue(label, v)
|
||||
if v := group.Alerts[0].Labels.Get(label); v != nil {
|
||||
return resolveLabelValue(label, v.Value)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -283,14 +283,14 @@ func autoGridLabel(dedupedAlerts []models.AlertGroup) string {
|
||||
for _, ag := range dedupedAlerts {
|
||||
alertsCount += ag.Alerts.Len()
|
||||
for _, alert := range ag.Alerts {
|
||||
for key, val := range alert.Labels {
|
||||
if _, ok := labelToAlertCount[key]; !ok {
|
||||
labelToAlertCount[key] = map[string]int{}
|
||||
for _, l := range alert.Labels {
|
||||
if _, ok := labelToAlertCount[l.Name]; !ok {
|
||||
labelToAlertCount[l.Name] = map[string]int{}
|
||||
}
|
||||
if _, ok := labelToAlertCount[key][val]; !ok {
|
||||
labelToAlertCount[key][val] = 0
|
||||
if _, ok := labelToAlertCount[l.Name][l.Value]; !ok {
|
||||
labelToAlertCount[l.Name][l.Value] = 0
|
||||
}
|
||||
labelToAlertCount[key][val]++
|
||||
labelToAlertCount[l.Name][l.Value]++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -18,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
type groupTest struct {
|
||||
labels map[string]string
|
||||
labels models.Labels
|
||||
receiver string
|
||||
alerts []models.Alert
|
||||
id string
|
||||
@@ -28,8 +29,8 @@ type groupTest struct {
|
||||
var groupTests = []groupTest{
|
||||
{
|
||||
receiver: "by-name",
|
||||
labels: map[string]string{
|
||||
"alertname": "Memory_Usage_Too_High",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Memory_Usage_Too_High"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -38,10 +39,10 @@ var groupTests = []groupTest{
|
||||
models.Annotation{Visible: true, Name: "alert", Value: "Memory usage exceeding threshold"},
|
||||
models.Annotation{Visible: true, Name: "dashboard", Value: "http://localhost/dashboard.html", IsLink: true},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"job": "node_exporter",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -64,9 +65,9 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-cluster-service",
|
||||
labels: map[string]string{
|
||||
"alertname": "Memory_Usage_Too_High",
|
||||
"cluster": "prod",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Memory_Usage_Too_High"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -83,9 +84,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server2",
|
||||
"job": "node_exporter",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -100,9 +101,9 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-cluster-service",
|
||||
labels: map[string]string{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "staging",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -116,9 +117,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server3",
|
||||
"ip": "127.0.0.3",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server3"},
|
||||
{Name: "ip", Value: "127.0.0.3"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -133,9 +134,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server4",
|
||||
"ip": "127.0.0.4",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server4"},
|
||||
{Name: "ip", Value: "127.0.0.4"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -150,9 +151,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server5",
|
||||
"ip": "127.0.0.5",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "ip", Value: "127.0.0.5"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -167,9 +168,9 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-cluster-service",
|
||||
labels: map[string]string{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "dev",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -183,9 +184,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{"168f139d-77e4-41d6-afb5-8fe2cfd0cc9d"},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server6",
|
||||
"ip": "127.0.0.6",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server6"},
|
||||
{Name: "ip", Value: "127.0.0.6"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -201,9 +202,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{"168f139d-77e4-41d6-afb5-8fe2cfd0cc9d", "378eaa69-097d-41c4-a8c2-fe6568c3abfc"},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server7",
|
||||
"ip": "127.0.0.7",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server7"},
|
||||
{Name: "ip", Value: "127.0.0.7"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -219,9 +220,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{"168f139d-77e4-41d6-afb5-8fe2cfd0cc9d"},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server8",
|
||||
"ip": "127.0.0.8",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server8"},
|
||||
{Name: "ip", Value: "127.0.0.8"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -236,8 +237,8 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-name",
|
||||
labels: map[string]string{
|
||||
"alertname": "Host_Down",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -245,10 +246,10 @@ var groupTests = []groupTest{
|
||||
Annotations: models.Annotations{
|
||||
models.Annotation{Visible: true, Name: "url", Value: "http://localhost/example.html", IsLink: true},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"cluster": "prod",
|
||||
"instance": "server1",
|
||||
"ip": "127.0.0.1",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server1"},
|
||||
{Name: "ip", Value: "127.0.0.1"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -264,10 +265,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 1, 0, 1, 0, 0, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"ip": "127.0.0.2",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "ip", Value: "127.0.0.2"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -283,10 +284,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 1, 0, 1, 0, 1, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "staging",
|
||||
"instance": "server3",
|
||||
"ip": "127.0.0.3",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "instance", Value: "server3"},
|
||||
{Name: "ip", Value: "127.0.0.3"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -302,10 +303,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 1, 0, 0, 59, 0, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "staging",
|
||||
"instance": "server4",
|
||||
"ip": "127.0.0.4",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "instance", Value: "server4"},
|
||||
{Name: "ip", Value: "127.0.0.4"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -321,10 +322,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 10, 0, 0, 0, 0, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "staging",
|
||||
"instance": "server5",
|
||||
"ip": "127.0.0.5",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "ip", Value: "127.0.0.5"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -340,10 +341,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 10, 1, 0, 0, 0, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "dev",
|
||||
"instance": "server6",
|
||||
"ip": "127.0.0.6",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "server6"},
|
||||
{Name: "ip", Value: "127.0.0.6"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -359,10 +360,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 10, 0, 20, 0, 0, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "dev",
|
||||
"instance": "server7",
|
||||
"ip": "127.0.0.7",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "server7"},
|
||||
{Name: "ip", Value: "127.0.0.7"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -378,10 +379,10 @@ var groupTests = []groupTest{
|
||||
{
|
||||
StartsAt: time.Date(2019, time.January, 10, 0, 21, 0, 0, time.UTC),
|
||||
Annotations: models.Annotations{},
|
||||
Labels: map[string]string{
|
||||
"cluster": "dev",
|
||||
"instance": "server8",
|
||||
"ip": "127.0.0.8",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "server8"},
|
||||
{Name: "ip", Value: "127.0.0.8"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Alertmanager: []models.AlertmanagerInstance{
|
||||
@@ -404,9 +405,9 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-cluster-service",
|
||||
labels: map[string]string{
|
||||
"alertname": "Free_Disk_Space_Too_Low",
|
||||
"cluster": "staging",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Free_Disk_Space_Too_Low"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -423,10 +424,10 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server5",
|
||||
"job": "node_exporter",
|
||||
"disk": "sda",
|
||||
Labels: models.Labels{
|
||||
{Name: "disk", Value: "sda"},
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -441,9 +442,9 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-cluster-service",
|
||||
labels: map[string]string{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "prod",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -459,9 +460,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server1",
|
||||
"ip": "127.0.0.1",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server1"},
|
||||
{Name: "ip", Value: "127.0.0.1"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -476,9 +477,9 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "server2",
|
||||
"ip": "127.0.0.2",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "ip", Value: "127.0.0.2"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -493,8 +494,8 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-name",
|
||||
labels: map[string]string{
|
||||
"alertname": "HTTP_Probe_Failed",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "HTTP_Probe_Failed"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -510,8 +511,8 @@ var groupTests = []groupTest{
|
||||
Source: "http://localhost/prometheus",
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "web1",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "web1"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Receiver: "by-name",
|
||||
@@ -527,8 +528,8 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "web2",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "web2"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-name",
|
||||
@@ -543,8 +544,8 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-name",
|
||||
labels: map[string]string{
|
||||
"alertname": "Free_Disk_Space_Too_Low",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "Free_Disk_Space_Too_Low"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -561,11 +562,11 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"cluster": "staging",
|
||||
"instance": "server5",
|
||||
"job": "node_exporter",
|
||||
"disk": "sda",
|
||||
Labels: models.Labels{
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "disk", Value: "sda"},
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-name",
|
||||
@@ -580,9 +581,9 @@ var groupTests = []groupTest{
|
||||
},
|
||||
{
|
||||
receiver: "by-cluster-service",
|
||||
labels: map[string]string{
|
||||
"alertname": "HTTP_Probe_Failed",
|
||||
"cluster": "dev",
|
||||
labels: models.Labels{
|
||||
{Name: "alertname", Value: "HTTP_Probe_Failed"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
},
|
||||
alerts: []models.Alert{
|
||||
{
|
||||
@@ -599,8 +600,8 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{"0804764c-6163-4c64-b0a9-08feebe2db4b"},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "web1",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "web1"},
|
||||
},
|
||||
State: models.AlertStateSuppressed,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -616,8 +617,8 @@ var groupTests = []groupTest{
|
||||
SilencedBy: []string{},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"instance": "web2",
|
||||
Labels: models.Labels{
|
||||
{Name: "instance", Value: "web2"},
|
||||
},
|
||||
State: models.AlertStateActive,
|
||||
Receiver: "by-cluster-service",
|
||||
@@ -641,12 +642,12 @@ func compareAlertGroups(testCase groupTest, group models.APIAlertGroup) bool {
|
||||
if len(testCase.labels) != len(group.Labels) {
|
||||
return false
|
||||
}
|
||||
for key, val := range testCase.labels {
|
||||
v, found := group.Labels[key]
|
||||
if !found {
|
||||
for _, l := range testCase.labels {
|
||||
v := group.Labels.Get(l.Name)
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
if val != v {
|
||||
if l.Value != v.Value {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -660,12 +661,12 @@ func compareAlerts(expectedAlert, gotAlert models.Alert) bool {
|
||||
if len(gotAlert.Labels) != len(expectedAlert.Labels) {
|
||||
return false
|
||||
}
|
||||
for key, val := range expectedAlert.Labels {
|
||||
v, found := gotAlert.Labels[key]
|
||||
if !found {
|
||||
for _, l := range expectedAlert.Labels {
|
||||
v := gotAlert.Labels.Get(l.Name)
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
if val != v {
|
||||
if l.Value != v.Value {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1000,22 +1001,23 @@ func TestSortOrder(t *testing.T) {
|
||||
} else {
|
||||
values := []string{}
|
||||
for _, ag := range ur.Grids[0].AlertGroups {
|
||||
v := ag.Labels[testCase.expectedLabel]
|
||||
v := ag.Labels.GetValue(testCase.expectedLabel)
|
||||
if v == "" {
|
||||
v = ag.Shared.Labels[testCase.expectedLabel]
|
||||
v = ag.Shared.Labels.GetValue(testCase.expectedLabel)
|
||||
}
|
||||
if v != "" {
|
||||
values = append(values, v)
|
||||
} else {
|
||||
for _, alert := range ag.Alerts {
|
||||
v = alert.Labels[testCase.expectedLabel]
|
||||
v = alert.Labels.GetValue(testCase.expectedLabel)
|
||||
values = append(values, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(testCase.expectedValues, values); diff != "" {
|
||||
t.Errorf("Incorrectly sorted values (-want +got):\n%s", diff)
|
||||
t.Errorf("Incorrectly sorted values for filter=%q order=%s label=%q reverse=%v (-want +got):\n%s",
|
||||
strings.Join(testCase.filter, " "), testCase.sortOrder, testCase.sortLabel, testCase.sortReverse, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1023,22 +1025,22 @@ func TestSortOrder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func verifyStrippedLabels(t *testing.T, labels map[string]string, keep, strip []string) {
|
||||
func verifyStrippedLabels(t *testing.T, labels models.Labels, keep, strip []string) {
|
||||
for _, l := range strip {
|
||||
if val, ok := labels[l]; ok {
|
||||
t.Errorf("Found stripped label %s=%s on %v", l, val, labels)
|
||||
if val := labels.Get(l); val != nil {
|
||||
t.Errorf("Found stripped label %s=%s on %v", val.Name, val.Value, labels)
|
||||
}
|
||||
}
|
||||
if len(keep) > 0 && len(strip) == 0 {
|
||||
for k, v := range labels {
|
||||
for _, ll := range labels {
|
||||
ok := false
|
||||
for _, l := range keep {
|
||||
if k == l {
|
||||
if ll.Name == l {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf("Found label %s=%s that's not on the keep list: %v", k, v, keep)
|
||||
t.Errorf("Found label %s=%s that's not on the keep list: %v", ll.Name, ll.Value, keep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,6 @@ func alerts(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// use full URI (including query args) as cache key
|
||||
cacheKey := fmt.Sprintf("%x", structhash.Sha1(request, 1))
|
||||
|
||||
data, found := apiCache.Get(cacheKey)
|
||||
@@ -265,14 +264,14 @@ func alerts(w http.ResponseWriter, r *http.Request) {
|
||||
for _, ag := range filtered {
|
||||
perGridAlertGroup := map[string]*models.AlertGroup{}
|
||||
|
||||
for k := range ag.Labels {
|
||||
labelMap[k] = struct{}{}
|
||||
for _, l := range ag.Labels {
|
||||
labelMap[l.Name] = struct{}{}
|
||||
}
|
||||
for _, alert := range ag.Alerts {
|
||||
alert := alert // scopelint pin
|
||||
|
||||
for k := range alert.Labels {
|
||||
labelMap[k] = struct{}{}
|
||||
for _, l := range alert.Labels {
|
||||
labelMap[l.Name] = struct{}{}
|
||||
}
|
||||
|
||||
allReceivers[alert.Receiver] = true
|
||||
@@ -292,7 +291,7 @@ func alerts(w http.ResponseWriter, r *http.Request) {
|
||||
alertGridLabelValues[am.Cluster] = true
|
||||
}
|
||||
default:
|
||||
alertGridLabelValues[alert.Labels[gridLabel]] = true
|
||||
alertGridLabelValues[alert.Labels.GetValue(gridLabel)] = true
|
||||
}
|
||||
|
||||
for alertGridLabelValue := range alertGridLabelValues {
|
||||
@@ -390,13 +389,13 @@ func alerts(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range alert.Labels {
|
||||
if keyMap, foundKey := dedupedColors[key]; foundKey {
|
||||
if color, foundColor := keyMap[value]; foundColor {
|
||||
if _, found := colors[key]; !found {
|
||||
colors[key] = map[string]models.LabelColors{}
|
||||
for _, l := range alert.Labels {
|
||||
if keyMap, foundKey := dedupedColors[l.Name]; foundKey {
|
||||
if color, foundColor := keyMap[l.Value]; foundColor {
|
||||
if _, found := colors[l.Name]; !found {
|
||||
colors[l.Name] = map[string]models.LabelColors{}
|
||||
}
|
||||
colors[key][value] = color
|
||||
colors[l.Name][l.Value] = color
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -684,7 +683,7 @@ func silences(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type AlertList struct {
|
||||
Alerts []map[string]string `json:"alerts"`
|
||||
Alerts []models.Labels `json:"alerts"`
|
||||
}
|
||||
|
||||
func alertList(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -711,12 +710,9 @@ func alertList(w http.ResponseWriter, r *http.Request) {
|
||||
labelMap := map[string]map[string]string{}
|
||||
for _, ag := range filtered {
|
||||
for _, alert := range ag.Alerts {
|
||||
labels := map[string]string{}
|
||||
for k, v := range ag.Labels {
|
||||
labels[k] = v
|
||||
}
|
||||
for k, v := range alert.Labels {
|
||||
labels[k] = v
|
||||
labels := ag.Labels.Map()
|
||||
for _, l := range alert.Labels {
|
||||
labels[l.Name] = l.Value
|
||||
}
|
||||
h := fmt.Sprintf("%x", structhash.Sha1(labels, 1))
|
||||
labelMap[h] = labels
|
||||
@@ -736,10 +732,15 @@ func alertList(w http.ResponseWriter, r *http.Request) {
|
||||
sort.Strings(sortKeys)
|
||||
|
||||
al := AlertList{
|
||||
Alerts: []map[string]string{},
|
||||
Alerts: []models.Labels{},
|
||||
}
|
||||
for _, labels := range labelMap {
|
||||
al.Alerts = append(al.Alerts, labels)
|
||||
alert := models.Labels{}
|
||||
for k, v := range labels {
|
||||
alert = alert.Set(k, v)
|
||||
}
|
||||
sort.Sort(alert)
|
||||
al.Alerts = append(al.Alerts, alert)
|
||||
}
|
||||
sortSliceOfLabels(al.Alerts, sortKeys, "alertname")
|
||||
|
||||
@@ -751,20 +752,22 @@ func alertList(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write(data)
|
||||
}
|
||||
|
||||
func sortSliceOfLabels(labels []map[string]string, sortKeys []string, fallback string) {
|
||||
func sortSliceOfLabels(labels []models.Labels, sortKeys []string, fallback string) {
|
||||
sort.SliceStable(labels, func(i, j int) bool {
|
||||
for _, k := range sortKeys {
|
||||
if labels[i][k] != "" && labels[j][k] == "" {
|
||||
vi := labels[i].GetValue(k)
|
||||
vj := labels[j].GetValue(k)
|
||||
if vi != "" && vj == "" {
|
||||
return true
|
||||
}
|
||||
if labels[i][k] == "" && labels[j][k] != "" {
|
||||
if vi == "" && vj != "" {
|
||||
return false
|
||||
}
|
||||
if labels[i][k] != labels[j][k] {
|
||||
return sortorder.NaturalLess(labels[i][k], labels[j][k])
|
||||
if vi != vj {
|
||||
return sortorder.NaturalLess(vi, vj)
|
||||
}
|
||||
}
|
||||
return sortorder.NaturalLess(labels[i][fallback], labels[j][fallback])
|
||||
return sortorder.NaturalLess(labels[i].GetValue(fallback), labels[j].GetValue(fallback))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -814,8 +817,8 @@ func counters(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
countLabel(counters, "@state", alert.State)
|
||||
countLabel(counters, "@receiver", alert.Receiver)
|
||||
for key, value := range alert.Labels {
|
||||
countLabel(counters, key, value)
|
||||
for _, l := range alert.Labels {
|
||||
countLabel(counters, l.Name, l.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3474,87 +3474,87 @@ func TestAlertList(t *testing.T) {
|
||||
{
|
||||
args: "",
|
||||
alerts: AlertList{
|
||||
Alerts: []map[string]string{
|
||||
Alerts: []models.Labels{
|
||||
{
|
||||
"alertname": "Free_Disk_Space_Too_Low",
|
||||
"cluster": "staging",
|
||||
"disk": "sda",
|
||||
"instance": "server5",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "Free_Disk_Space_Too_Low"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "disk", Value: "sda"},
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
{
|
||||
"alertname": "HTTP_Probe_Failed",
|
||||
"cluster": "dev",
|
||||
"instance": "web1",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "HTTP_Probe_Failed"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "web1"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
{
|
||||
"alertname": "HTTP_Probe_Failed",
|
||||
"cluster": "dev",
|
||||
"instance": "web2",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "HTTP_Probe_Failed"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "web2"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "dev",
|
||||
"instance": "server6",
|
||||
"ip": "127.0.0.6",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "server6"},
|
||||
{Name: "ip", Value: "127.0.0.6"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "dev",
|
||||
"instance": "server7",
|
||||
"ip": "127.0.0.7",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "server7"},
|
||||
{Name: "ip", Value: "127.0.0.7"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "dev",
|
||||
"instance": "server8",
|
||||
"ip": "127.0.0.8",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "server8"},
|
||||
{Name: "ip", Value: "127.0.0.8"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "prod",
|
||||
"instance": "server1",
|
||||
"ip": "127.0.0.1",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server1"},
|
||||
{Name: "ip", Value: "127.0.0.1"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"ip": "127.0.0.2",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "ip", Value: "127.0.0.2"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "staging",
|
||||
"instance": "server3",
|
||||
"ip": "127.0.0.3",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "instance", Value: "server3"},
|
||||
{Name: "ip", Value: "127.0.0.3"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "staging",
|
||||
"instance": "server4",
|
||||
"ip": "127.0.0.4",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "instance", Value: "server4"},
|
||||
{Name: "ip", Value: "127.0.0.4"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "staging",
|
||||
"instance": "server5",
|
||||
"ip": "127.0.0.5",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "ip", Value: "127.0.0.5"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Memory_Usage_Too_High",
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "Memory_Usage_Too_High"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3562,13 +3562,13 @@ func TestAlertList(t *testing.T) {
|
||||
{
|
||||
args: "q=alertname=Free_Disk_Space_Too_Low",
|
||||
alerts: AlertList{
|
||||
Alerts: []map[string]string{
|
||||
Alerts: []models.Labels{
|
||||
{
|
||||
"alertname": "Free_Disk_Space_Too_Low",
|
||||
"cluster": "staging",
|
||||
"disk": "sda",
|
||||
"instance": "server5",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "Free_Disk_Space_Too_Low"},
|
||||
{Name: "cluster", Value: "staging"},
|
||||
{Name: "disk", Value: "sda"},
|
||||
{Name: "instance", Value: "server5"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3576,18 +3576,18 @@ func TestAlertList(t *testing.T) {
|
||||
{
|
||||
args: "q=alertname=HTTP_Probe_Failed",
|
||||
alerts: AlertList{
|
||||
Alerts: []map[string]string{
|
||||
Alerts: []models.Labels{
|
||||
{
|
||||
"alertname": "HTTP_Probe_Failed",
|
||||
"cluster": "dev",
|
||||
"instance": "web1",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "HTTP_Probe_Failed"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "web1"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
{
|
||||
"alertname": "HTTP_Probe_Failed",
|
||||
"cluster": "dev",
|
||||
"instance": "web2",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "HTTP_Probe_Failed"},
|
||||
{Name: "cluster", Value: "dev"},
|
||||
{Name: "instance", Value: "web2"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3595,19 +3595,19 @@ func TestAlertList(t *testing.T) {
|
||||
{
|
||||
args: "q=instance=server2",
|
||||
alerts: AlertList{
|
||||
Alerts: []map[string]string{
|
||||
Alerts: []models.Labels{
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"ip": "127.0.0.2",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "ip", Value: "127.0.0.2"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Memory_Usage_Too_High",
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"job": "node_exporter",
|
||||
{Name: "alertname", Value: "Memory_Usage_Too_High"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "job", Value: "node_exporter"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3615,20 +3615,20 @@ func TestAlertList(t *testing.T) {
|
||||
{
|
||||
args: "q=alertname=Host_Down&q=cluster=prod",
|
||||
alerts: AlertList{
|
||||
Alerts: []map[string]string{
|
||||
Alerts: []models.Labels{
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "prod",
|
||||
"instance": "server1",
|
||||
"ip": "127.0.0.1",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server1"},
|
||||
{Name: "ip", Value: "127.0.0.1"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
{
|
||||
"alertname": "Host_Down",
|
||||
"cluster": "prod",
|
||||
"instance": "server2",
|
||||
"ip": "127.0.0.2",
|
||||
"job": "node_ping",
|
||||
{Name: "alertname", Value: "Host_Down"},
|
||||
{Name: "cluster", Value: "prod"},
|
||||
{Name: "instance", Value: "server2"},
|
||||
{Name: "ip", Value: "127.0.0.2"},
|
||||
{Name: "job", Value: "node_ping"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3636,7 +3636,7 @@ func TestAlertList(t *testing.T) {
|
||||
{
|
||||
args: "q=foo=bar",
|
||||
alerts: AlertList{
|
||||
Alerts: []map[string]string{},
|
||||
Alerts: []models.Labels{},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -3675,85 +3675,85 @@ func TestAlertList(t *testing.T) {
|
||||
|
||||
func TestSortSliceOfLabels(t *testing.T) {
|
||||
type testCaseT struct {
|
||||
labels []map[string]string
|
||||
labels []models.Labels
|
||||
sortKeys []string
|
||||
fallback string
|
||||
output []map[string]string
|
||||
output []models.Labels
|
||||
}
|
||||
|
||||
testCases := []testCaseT{
|
||||
{
|
||||
labels: []map[string]string{
|
||||
{"alertname": "alert2"},
|
||||
{"alertname": "alert1"},
|
||||
labels: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
sortKeys: []string{},
|
||||
fallback: "",
|
||||
output: []map[string]string{
|
||||
{"alertname": "alert2"},
|
||||
{"alertname": "alert1"},
|
||||
output: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: []map[string]string{
|
||||
{"alertname": "alert2"},
|
||||
{"alertname": "alert1"},
|
||||
labels: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
sortKeys: []string{"alertname"},
|
||||
fallback: "alertname",
|
||||
output: []map[string]string{
|
||||
{"alertname": "alert1"},
|
||||
{"alertname": "alert2"},
|
||||
output: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: []map[string]string{
|
||||
{"alertname": "alert2"},
|
||||
{"alertname": "alert1"},
|
||||
labels: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
sortKeys: []string{},
|
||||
fallback: "alertname",
|
||||
output: []map[string]string{
|
||||
{"alertname": "alert1"},
|
||||
{"alertname": "alert2"},
|
||||
output: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: []map[string]string{
|
||||
{"alertname": "alert2"},
|
||||
{"alertname": "alert1"},
|
||||
labels: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
sortKeys: []string{"foo"},
|
||||
fallback: "alertname",
|
||||
output: []map[string]string{
|
||||
{"alertname": "alert1"},
|
||||
{"alertname": "alert2"},
|
||||
output: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
{{Name: "alertname", Value: "alert2"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: []map[string]string{
|
||||
{"alertname": "alert1"},
|
||||
{"alertname": "alert1"},
|
||||
labels: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
sortKeys: []string{"alertname"},
|
||||
fallback: "alertname",
|
||||
output: []map[string]string{
|
||||
{"alertname": "alert1"},
|
||||
{"alertname": "alert1"},
|
||||
output: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: []map[string]string{
|
||||
{"alertname": "alert2", "job": "a"},
|
||||
{"alertname": "alert1"},
|
||||
{"alertname": "alert3", "job": "b"},
|
||||
labels: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}, {Name: "job", Value: "a"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
{{Name: "alertname", Value: "alert3"}, {Name: "job", Value: "b"}},
|
||||
},
|
||||
sortKeys: []string{"job"},
|
||||
fallback: "alertname",
|
||||
output: []map[string]string{
|
||||
{"alertname": "alert2", "job": "a"},
|
||||
{"alertname": "alert3", "job": "b"},
|
||||
{"alertname": "alert1"},
|
||||
output: []models.Labels{
|
||||
{{Name: "alertname", Value: "alert2"}, {Name: "job", Value: "a"}},
|
||||
{{Name: "alertname", Value: "alert3"}, {Name: "job", Value: "b"}},
|
||||
{{Name: "alertname", Value: "alert1"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user