/
base.go
148 lines (122 loc) · 4.08 KB
/
base.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package notifiers
import (
"context"
"time"
"github.com/Fenrislol/grafana/pkg/infra/log"
"github.com/Fenrislol/grafana/pkg/models"
"github.com/Fenrislol/grafana/pkg/services/alerting"
)
const (
triggMetrString = "Triggered metrics:\n\n"
)
// NotifierBase is the base implementation of a notifier.
type NotifierBase struct {
Name string
Type string
UID string
IsDefault bool
UploadImage bool
SendReminder bool
DisableResolveMessage bool
Frequency time.Duration
log log.Logger
}
// NewNotifierBase returns a new `NotifierBase`.
func NewNotifierBase(model *models.AlertNotification) NotifierBase {
uploadImage := true
value, exist := model.Settings.CheckGet("uploadImage")
if exist {
uploadImage = value.MustBool()
}
return NotifierBase{
UID: model.Uid,
Name: model.Name,
IsDefault: model.IsDefault,
Type: model.Type,
UploadImage: uploadImage,
SendReminder: model.SendReminder,
DisableResolveMessage: model.DisableResolveMessage,
Frequency: model.Frequency,
log: log.New("alerting.notifier." + model.Name),
}
}
// ShouldNotify checks this evaluation should send an alert notification
func (n *NotifierBase) ShouldNotify(ctx context.Context, context *alerting.EvalContext, notifierState *models.AlertNotificationState) bool {
prevState := context.PrevAlertState
newState := context.Rule.State
// Only notify on state change.
if prevState == newState && !n.SendReminder {
return false
}
if prevState == newState && n.SendReminder {
// Do not notify if interval has not elapsed
lastNotify := time.Unix(notifierState.UpdatedAt, 0)
if notifierState.UpdatedAt != 0 && lastNotify.Add(n.Frequency).After(time.Now()) {
return false
}
// Do not notify if alert state is OK or pending even on repeated notify
if newState == models.AlertStateOK || newState == models.AlertStatePending {
return false
}
}
okOrPending := newState == models.AlertStatePending || newState == models.AlertStateOK
// Do not notify when new state is ok/pending when previous is unknown
if prevState == models.AlertStateUnknown && okOrPending {
return false
}
// Do not notify when we become Pending for the first
if prevState == models.AlertStateNoData && newState == models.AlertStatePending {
return false
}
// Do not notify when we become OK from pending
if prevState == models.AlertStatePending && newState == models.AlertStateOK {
return false
}
// Do not notify when we OK -> Pending
if prevState == models.AlertStateOK && newState == models.AlertStatePending {
return false
}
// Do not notify if state pending and it have been updated last minute
if notifierState.State == models.AlertNotificationStatePending {
lastUpdated := time.Unix(notifierState.UpdatedAt, 0)
if lastUpdated.Add(1 * time.Minute).After(time.Now()) {
return false
}
}
// Do not notify when state is OK if DisableResolveMessage is set to true
if newState == models.AlertStateOK && n.DisableResolveMessage {
return false
}
return true
}
// GetType returns the notifier type.
func (n *NotifierBase) GetType() string {
return n.Type
}
// NeedsImage returns true if an image is expected in the notification.
func (n *NotifierBase) NeedsImage() bool {
return n.UploadImage
}
// GetNotifierUID returns the notifier `uid`.
func (n *NotifierBase) GetNotifierUID() string {
return n.UID
}
// GetIsDefault returns true if the notifiers should
// be used for all alerts.
func (n *NotifierBase) GetIsDefault() bool {
return n.IsDefault
}
// GetSendReminder returns true if reminders should be sent.
func (n *NotifierBase) GetSendReminder() bool {
return n.SendReminder
}
// GetDisableResolveMessage returns true if ok alert notifications
// should be skipped.
func (n *NotifierBase) GetDisableResolveMessage() bool {
return n.DisableResolveMessage
}
// GetFrequency returns the frequency for how often
// alerts should be evaluated.
func (n *NotifierBase) GetFrequency() time.Duration {
return n.Frequency
}