Add --receivers.keep for consistency with other options

there's --labels.keep so same should apply to receivers, add new option, tests and fixes as it wasn't working properly
This commit is contained in:
Łukasz Mierzwa
2017-12-02 21:51:31 -08:00
parent 5f904ec99d
commit 860375650e
7 changed files with 116 additions and 28 deletions
+13 -6
View File
@@ -355,19 +355,19 @@ jira: []
### Receivers
`receivers` section allows configuring how alerts from different receivers are
handled by unsee.
handled by unsee. If alerts are routed to multiple receivers they can be
duplicated in the UI, each instance will have different value for `@receiver`.
Syntax:
```yaml
receivers:
keep: list of strings
strip: list of strings
```
* `strip` - list of receiver names that should be ignored when collecting data
from Alertmanager API. If alerts are routed to multiple receivers they can be
duplicated in the UI, each instance will have different value for `@receiver`.
This options allows to set a list of receivers that will not be shown in the
UI.
* `keep` - list of receivers name that are allowed, if empty all receivers are
allowed.
* `strip` - list of receiver names that will not be shown in the UI.
Example where alerts that are routed to the `alertmanage2es` receiver are
ignored by unsee.
@@ -433,3 +433,10 @@ Exaceptions:
Environment variables are mapped in a similiar way as command line flags,
`alertmanager:interval` is accessible as `ALERTMANAGER_INTERVAL` env.
Same exceptions apply as with command line flags.
* `HOST` - used by gin webserver, same effect as setting `listen:address` config
option
* `PORT` - used by gin webserver, same effect as setting `listen:port` config
option
* `SENTRY_DSN` - is used by Sentry itself, same effect as passing value to
`sentry:private` config option.
+9 -5
View File
@@ -31,6 +31,11 @@ func DedupAlerts() []models.AlertGroup {
alerts := map[string]models.Alert{}
for _, ag := range agList {
for _, alert := range ag.Alerts {
// remove all alerts for receiver(s) that the user doesn't
// want to see in the UI
if transform.StripReceivers(config.Config.Receivers.Keep, config.Config.Receivers.Strip, alert.Receiver) {
continue
}
alertLFP := alert.LabelsFingerprint()
a, found := alerts[alertLFP]
if found {
@@ -60,14 +65,13 @@ func DedupAlerts() []models.AlertGroup {
}
}
}
// skip empty groups
if len(alerts) == 0 {
continue
}
ag := models.AlertGroup(agList[0])
ag.Alerts = models.AlertList{}
for _, alert := range alerts {
// remove all alerts for receiver(s) that the user doesn't
// want to see in the UI
if transform.StripReceivers(config.Config.Receivers.Strip, alert.Receiver) {
continue
}
// strip labels user doesn't want to see in the UI
alert.Labels = transform.StripLables(config.Config.Labels.Keep, config.Config.Labels.Strip, alert.Labels)
// calculate final alert state based on the most important value found
+13
View File
@@ -99,3 +99,16 @@ func TestDedupColors(t *testing.T) {
t.Errorf("Expected %d color keys, got %d", expected, len(colors))
}
}
func TestStripReceivers(t *testing.T) {
os.Setenv("RECEIVERS_STRIP", "by-name by-cluster-service")
os.Setenv("ALERTMANAGER_URI", "http://localhost")
config.Config.Read()
if err := pullAlerts(); err != nil {
t.Error(err)
}
alerts := alertmanager.DedupAlerts()
if len(alerts) > 0 {
t.Errorf("Expected no alerts after stripping all receivers, got %d", len(alerts))
}
}
+3
View File
@@ -58,6 +58,8 @@ func init() {
pflag.String("log.level", "info",
"Log level, one of: debug, info, warning, error, fatal and panic")
pflag.StringSlice("receivers.keep", []string{},
"List of receivers to keep, all alerts with different receivers will be ignored")
pflag.StringSlice("receivers.strip", []string{},
"List of receivers to not display alerts for")
@@ -121,6 +123,7 @@ func (config *configSchema) Read() {
config.Listen.Prefix = v.GetString("listen.prefix")
config.Log.Config = v.GetBool("log.config")
config.Log.Level = v.GetString("log.level")
config.Receivers.Keep = v.GetStringSlice("receivers.keep")
config.Receivers.Strip = v.GetStringSlice("receivers.strip")
config.Sentry.Private = v.GetString("sentry.private")
config.Sentry.Public = v.GetString("sentry.public")
+2 -1
View File
@@ -36,8 +36,8 @@ type configSchema struct {
Default []string
}
Labels struct {
Strip []string
Keep []string
Strip []string
}
Listen struct {
Address string
@@ -50,6 +50,7 @@ type configSchema struct {
}
JIRA []jiraRule
Receivers struct {
Keep []string
Strip []string
}
Sentry struct {
+11 -6
View File
@@ -28,11 +28,16 @@ func StripLables(keptLabels, ignoredLabels []string, sourceLabels map[string]str
}
// StripReceivers allows filtering all alerts for specified receiver(s)
func StripReceivers(ignoredReceivers []string, alertReceiver string) bool {
for _, ignoredReceiver := range ignoredReceivers {
if alertReceiver == ignoredReceiver {
return true
}
// it will return true if alert uses receiver that should be stripped
func StripReceivers(keptReceivers, ignoredReceivers []string, alertReceiver string) bool {
// true if we keep by default
keepAll := len(keptReceivers) == 0
// is this receiver on the whitelist ?
inKeep := slices.StringInSlice(keptReceivers, alertReceiver)
// is this receiver on the blacklist ?
inStrip := slices.StringInSlice(ignoredReceivers, alertReceiver)
if (keepAll || inKeep) && !inStrip {
return false
}
return false
return true
}
+65 -10
View File
@@ -7,15 +7,15 @@ import (
"github.com/cloudflare/unsee/internal/transform"
)
type stripTest struct {
type stripLabelTest struct {
strip []string
keep []string
before map[string]string
after map[string]string
}
var stripTests = []stripTest{
stripTest{
var stripLabelTests = []stripLabelTest{
stripLabelTest{
strip: []string{"env"},
keep: []string{},
before: map[string]string{
@@ -28,7 +28,7 @@ var stripTests = []stripTest{
"level": "info",
},
},
stripTest{
stripLabelTest{
strip: []string{"server"},
keep: []string{},
before: map[string]string{
@@ -42,7 +42,7 @@ var stripTests = []stripTest{
"level": "info",
},
},
stripTest{
stripLabelTest{
strip: []string{},
keep: []string{},
before: map[string]string{
@@ -56,7 +56,7 @@ var stripTests = []stripTest{
"level": "info",
},
},
stripTest{
stripLabelTest{
strip: []string{"host"},
keep: []string{},
before: map[string]string{
@@ -64,7 +64,7 @@ var stripTests = []stripTest{
},
after: map[string]string{},
},
stripTest{
stripLabelTest{
strip: []string{},
keep: []string{"env"},
before: map[string]string{
@@ -76,7 +76,7 @@ var stripTests = []stripTest{
"env": "production",
},
},
stripTest{
stripLabelTest{
strip: []string{"env"},
keep: []string{"host"},
before: map[string]string{
@@ -88,7 +88,7 @@ var stripTests = []stripTest{
"host": "localhost",
},
},
stripTest{
stripLabelTest{
strip: []string{},
keep: []string{"env"},
before: map[string]string{
@@ -100,10 +100,65 @@ var stripTests = []stripTest{
}
func TestStripLables(t *testing.T) {
for _, testCase := range stripTests {
for _, testCase := range stripLabelTests {
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)
}
}
}
type stripReceiverTest struct {
strip []string
keep []string
receiver string
stripped bool
}
var stripReceiverTests = []stripReceiverTest{
stripReceiverTest{
strip: []string{},
keep: []string{},
receiver: "default",
stripped: false,
},
stripReceiverTest{
strip: []string{"default"},
keep: []string{},
receiver: "default",
stripped: true,
},
stripReceiverTest{
strip: []string{"default"},
keep: []string{"default"},
receiver: "default",
stripped: true,
},
stripReceiverTest{
strip: []string{},
keep: []string{"default"},
receiver: "default",
stripped: false,
},
stripReceiverTest{
strip: []string{"foo", "bar"},
keep: []string{},
receiver: "default",
stripped: false,
},
stripReceiverTest{
strip: []string{"foo", "default"},
keep: []string{"foo", "bar"},
receiver: "default",
stripped: true,
},
}
func TestStripReceivers(t *testing.T) {
for _, testCase := range stripReceiverTests {
stripped := transform.StripReceivers(testCase.keep, testCase.strip, testCase.receiver)
if stripped != testCase.stripped {
t.Errorf("StripReceivers failed, expected %v, got %v", testCase.stripped, stripped)
}
}
}