-
Notifications
You must be signed in to change notification settings - Fork 24
/
alerter.go
94 lines (79 loc) · 2.47 KB
/
alerter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package alerts
import (
"strings"
"github.com/fluxninja/aperture/v2/pkg/config"
)
// AlertsFxTag - name tag for alerter in fx.
var AlertsFxTag = config.NameTag("AlertsFx")
// Alerter is responsible for receiving alerts and propagating them to the channel
// returned by AlertsChan().
type Alerter interface {
AddAlert(*Alert)
AlertsChan() <-chan *Alert
WithLabels(map[string]string) Alerter
}
// SimpleAlerter implements Alerter interface. It just simple propagates alerts
// to the channel.
type SimpleAlerter struct {
alertsCh chan *Alert
}
// NewSimpleAlerter returns new instance of SimpleAlerter with channel of given size.
func NewSimpleAlerter(channelSize int) Alerter {
return &SimpleAlerter{
alertsCh: make(chan *Alert, channelSize),
}
}
// AddAlert adds alert to the channel.
func (a *SimpleAlerter) AddAlert(alert *Alert) {
a.alertsCh <- alert
}
// AlertsChan returns the alerts channel.
func (a *SimpleAlerter) AlertsChan() <-chan *Alert {
return a.alertsCh
}
// WithLabels returns the alerter wrapper with specified labels.
func (a *SimpleAlerter) WithLabels(labels map[string]string) Alerter {
return newAlerterWrapper(a, sanitizeKeysInLabels(labels))
}
type alerterWrapper struct {
parentAlerter Alerter
labels map[string]string
}
func newAlerterWrapper(parent Alerter, labels map[string]string) Alerter {
return &alerterWrapper{
parentAlerter: parent,
labels: labels,
}
}
// AddAlert adds alert to the channel with labels specified at wrapper creation.
func (aw *alerterWrapper) AddAlert(alert *Alert) {
for key, val := range aw.labels {
alert.SetLabel(key, val)
}
aw.parentAlerter.AddAlert(alert)
}
// AlertsChan returns the alerts channel.
func (aw *alerterWrapper) AlertsChan() <-chan *Alert {
return aw.parentAlerter.AlertsChan()
}
// WithLabels returns the alerter with new labels added to parent labels.
func (aw *alerterWrapper) WithLabels(labels map[string]string) Alerter {
mergedLabels := make(map[string]string)
for k, v := range aw.labels {
mergedLabels[k] = v
}
// overwrite older values with new ones
for k, v := range labels {
mergedLabels[k] = v
}
return newAlerterWrapper(aw, sanitizeKeysInLabels(mergedLabels))
}
func sanitizeKeysInLabels(labels map[string]string) map[string]string {
// change '-' to '_' in key because alertmanager does not accept it
fixedLabels := make(map[string]string)
for key, val := range labels {
fixedKey := strings.ReplaceAll(key, "-", "_")
fixedLabels[fixedKey] = val
}
return fixedLabels
}