diff --git a/README.md b/README.md index 402bb3608..6fa4be97c 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,21 @@ This option can also be set using `-jira.regex` flag. Example: This variable is optional and default is not set (no rule will be applied). +#### KEEP_LABELS + +List of label names to show on the UI, all other labels will be stripped. +This allows to hide all labels except selected few that are useful on the +alert dashboard. Accepts space separated list of label names. Examples: + + KEEP_LABELS=instance + KEEP_LABELS="host severity" + +This option can also be set using `-keep.labels` flag. Example: + + $ unsee -keep.labels "host severity" + +This variable is optional and default is not set (all labels will be shown). + #### PORT HTTP port to listen on. Example: diff --git a/internal/alertmanager/models.go b/internal/alertmanager/models.go index ba6149e04..65b638e6a 100644 --- a/internal/alertmanager/models.go +++ b/internal/alertmanager/models.go @@ -174,7 +174,7 @@ func (am *Alertmanager) pullAlerts(version string) error { } alert.Annotations, alert.Links = transform.DetectLinks(alert.Annotations) - alert.Labels = transform.StripLables(config.Config.StripLabels, alert.Labels) + alert.Labels = transform.StripLables(config.Config.KeepLabels, config.Config.StripLabels, alert.Labels) transform.ColorLabel(colors, "@receiver", alert.Receiver) for k, v := range alert.Labels { diff --git a/internal/config/config.go b/internal/config/config.go index 9ffed4ca0..9a503448b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -36,6 +36,7 @@ type configEnvs struct { SentryDSN string `envconfig:"SENTRY_DSN" help:"Sentry DSN for Go exceptions"` SentryPublicDSN string `envconfig:"SENTRY_PUBLIC_DSN" help:"Sentry DSN for javascript exceptions"` StripLabels spaceSeparatedList `envconfig:"STRIP_LABELS" help:"List of labels to ignore"` + KeepLabels spaceSeparatedList `envconfig:"KEEP_LABELS" help:"List of labels to keep, all other labels will be stripped"` WebPrefix string `envconfig:"WEB_PREFIX" default:"/" help:"URL prefix"` } diff --git a/internal/transform/strip.go b/internal/transform/strip.go index 91b9c71c4..7e25a115d 100644 --- a/internal/transform/strip.go +++ b/internal/transform/strip.go @@ -9,10 +9,16 @@ import ( // StripLables allows filtering out some labels from alerts // it takes the list of label keys to ignore and alert label map // it will return label map without labels found on the ignore list -func StripLables(ignoredLabels []string, sourceLabels map[string]string) map[string]string { +func StripLables(keptLabels, ignoredLabels []string, sourceLabels map[string]string) map[string]string { + // empty keep list means keep everything by default + keepAll := len(keptLabels) == 0 labels := map[string]string{} for label, value := range sourceLabels { - if !slices.StringInSlice(ignoredLabels, label) { + // is explicitly marked to be kept + inKeep := slices.StringInSlice(keptLabels, label) + // is explicitly marked to be stripped + inStrip := slices.StringInSlice(ignoredLabels, label) + if (keepAll || inKeep) && !inStrip { // strip leading and trailung space in label value // this is to normalize values in case space is added by Alertmanager rules labels[label] = strings.TrimSpace(value) diff --git a/internal/transform/strip_test.go b/internal/transform/strip_test.go index 2152588ea..a73f8d8f6 100644 --- a/internal/transform/strip_test.go +++ b/internal/transform/strip_test.go @@ -9,6 +9,7 @@ import ( type stripTest struct { strip []string + keep []string before map[string]string after map[string]string } @@ -16,6 +17,7 @@ type stripTest struct { var stripTests = []stripTest{ stripTest{ strip: []string{"env"}, + keep: []string{}, before: map[string]string{ "host": "localhost", "env": "production", @@ -28,6 +30,7 @@ var stripTests = []stripTest{ }, stripTest{ strip: []string{"server"}, + keep: []string{}, before: map[string]string{ "host": "localhost", "env": "production", @@ -41,6 +44,7 @@ var stripTests = []stripTest{ }, stripTest{ strip: []string{}, + keep: []string{}, before: map[string]string{ "host": "localhost", "env": "production", @@ -54,16 +58,50 @@ var stripTests = []stripTest{ }, stripTest{ strip: []string{"host"}, + keep: []string{}, before: map[string]string{ "host": "localhost", }, after: map[string]string{}, }, + stripTest{ + strip: []string{}, + keep: []string{"env"}, + before: map[string]string{ + "host": "localhost", + "env": "production", + "level": "info", + }, + after: map[string]string{ + "env": "production", + }, + }, + stripTest{ + strip: []string{"env"}, + keep: []string{"host"}, + before: map[string]string{ + "host": "localhost", + "env": "production", + "level": "info", + }, + after: map[string]string{ + "host": "localhost", + }, + }, + stripTest{ + strip: []string{}, + keep: []string{"env"}, + before: map[string]string{ + "host": "localhost", + "level": "info", + }, + after: map[string]string{}, + }, } func TestStripLables(t *testing.T) { for _, testCase := range stripTests { - labels := transform.StripLables(testCase.strip, testCase.before) + labels := transform.StripLables(testCase.keep, testCase.strip, testCase.before) if !reflect.DeepEqual(labels, testCase.after) { t.Errorf("StripLables failed, expected %v, got %v", testCase.after, labels) }