mirror of
https://github.com/prymitive/karma
synced 2026-08-23 11:56:20 +00:00
Merge pull request #171 from cloudflare/include-labels
Implement KEEP_LABELS option
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -3,8 +3,10 @@ package alertmanager
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/cloudflare/unsee/internal/config"
|
||||
"github.com/cloudflare/unsee/internal/models"
|
||||
"github.com/cloudflare/unsee/internal/slices"
|
||||
"github.com/cloudflare/unsee/internal/transform"
|
||||
)
|
||||
|
||||
// DedupAlerts will collect alert groups from all defined Alertmanager
|
||||
@@ -61,6 +63,8 @@ func DedupAlerts() []models.AlertGroup {
|
||||
ag := models.AlertGroup(agList[0])
|
||||
ag.Alerts = models.AlertList{}
|
||||
for _, alert := range alerts {
|
||||
// strip labels user doesn't want to see in the UI
|
||||
alert.Labels = transform.StripLables(config.Config.KeepLabels, config.Config.StripLabels, alert.Labels)
|
||||
// calculate final alert state based on the most important value found
|
||||
// in the list of states from all instances
|
||||
alertLFP := alert.LabelsFingerprint()
|
||||
|
||||
@@ -35,9 +35,39 @@ func TestDedupAlerts(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
alertGroups := alertmanager.DedupAlerts()
|
||||
|
||||
if len(alertGroups) != 10 {
|
||||
t.Errorf("Expected %d alert groups, got %d", 10, len(alertGroups))
|
||||
}
|
||||
|
||||
totalAlerts := 0
|
||||
for _, ag := range alertGroups {
|
||||
totalAlerts += len(ag.Alerts)
|
||||
}
|
||||
if totalAlerts != 24 {
|
||||
t.Errorf("Expected %d total alerts, got %d", 24, totalAlerts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDedupAlertsWithoutLabels(t *testing.T) {
|
||||
config.Config.KeepLabels = []string{"xyz"}
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
alertGroups := alertmanager.DedupAlerts()
|
||||
config.Config.KeepLabels = []string{}
|
||||
|
||||
if len(alertGroups) != 10 {
|
||||
t.Errorf("Expected %d alert groups, got %d", 10, len(alertGroups))
|
||||
}
|
||||
|
||||
totalAlerts := 0
|
||||
for _, ag := range alertGroups {
|
||||
totalAlerts += len(ag.Alerts)
|
||||
}
|
||||
if totalAlerts != 24 {
|
||||
t.Errorf("Expected %d total alerts, got %d", 24, totalAlerts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDedupAutocomplete(t *testing.T) {
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/unsee/internal/config"
|
||||
"github.com/cloudflare/unsee/internal/mapper"
|
||||
"github.com/cloudflare/unsee/internal/models"
|
||||
"github.com/cloudflare/unsee/internal/transform"
|
||||
@@ -174,7 +173,6 @@ func (am *Alertmanager) pullAlerts(version string) error {
|
||||
}
|
||||
|
||||
alert.Annotations, alert.Links = transform.DetectLinks(alert.Annotations)
|
||||
alert.Labels = transform.StripLables(config.Config.StripLabels, alert.Labels)
|
||||
|
||||
transform.ColorLabel(colors, "@receiver", alert.Receiver)
|
||||
for k, v := range alert.Labels {
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user