mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Revert changes post code review and move them to notification page
This commit is contained in:
@@ -21,18 +21,17 @@ type AlertRule struct {
|
||||
ExecutionError string `json:"executionError"`
|
||||
Url string `json:"url"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
NotifyOnce bool `json:"notifyOnce"`
|
||||
NotifyEval uint64 `json:"notifyEval"`
|
||||
NotifyFreq uint64 `json:"notifyFrequency"`
|
||||
}
|
||||
|
||||
type AlertNotification struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
NotifyOnce bool `json:"notifyOnce"`
|
||||
Frequency bool `json:"frequency"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
}
|
||||
|
||||
type AlertTestCommand struct {
|
||||
@@ -62,9 +61,11 @@ type EvalMatch struct {
|
||||
}
|
||||
|
||||
type NotificationTestCommand struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
NotifyOnce bool `json:"notifyOnce"`
|
||||
Frequency time.Duration `json:"frequency"`
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
}
|
||||
|
||||
type PauseAlertCommand struct {
|
||||
|
||||
@@ -72,9 +72,6 @@ type Alert struct {
|
||||
Silenced bool
|
||||
ExecutionError string
|
||||
Frequency int64
|
||||
NotifyOnce bool
|
||||
NotifyFreq uint64
|
||||
NotifyEval uint64
|
||||
|
||||
EvalData *simplejson.Json
|
||||
NewStateDate time.Time
|
||||
@@ -98,8 +95,6 @@ func (this *Alert) ContainsUpdates(other *Alert) bool {
|
||||
result := false
|
||||
result = result || this.Name != other.Name
|
||||
result = result || this.Message != other.Message
|
||||
result = result || this.NotifyOnce != other.NotifyOnce
|
||||
result = result || (!other.NotifyOnce && this.NotifyFreq != other.NotifyFreq)
|
||||
|
||||
if this.Settings != nil && other.Settings != nil {
|
||||
json1, err1 := this.Settings.Encode()
|
||||
@@ -164,10 +159,6 @@ type SetAlertStateCommand struct {
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
type IncAlertEvalCommand struct {
|
||||
AlertId int64
|
||||
}
|
||||
|
||||
//Queries
|
||||
type GetAlertsQuery struct {
|
||||
OrgId int64
|
||||
|
||||
@@ -7,32 +7,38 @@ import (
|
||||
)
|
||||
|
||||
type AlertNotification struct {
|
||||
Id int64 `json:"id"`
|
||||
OrgId int64 `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Id int64 `json:"id"`
|
||||
OrgId int64 `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
NotifyOnce bool `json:"notifyOnce"`
|
||||
Frequency time.Duration `json:"frequency"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
}
|
||||
|
||||
type CreateAlertNotificationCommand struct {
|
||||
Name string `json:"name" binding:"Required"`
|
||||
Type string `json:"type" binding:"Required"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
Name string `json:"name" binding:"Required"`
|
||||
Type string `json:"type" binding:"Required"`
|
||||
NotifyOnce bool `json:"notifyOnce" binding:"Required"`
|
||||
Frequency time.Duration `json:"frequency"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
|
||||
OrgId int64 `json:"-"`
|
||||
Result *AlertNotification
|
||||
}
|
||||
|
||||
type UpdateAlertNotificationCommand struct {
|
||||
Id int64 `json:"id" binding:"Required"`
|
||||
Name string `json:"name" binding:"Required"`
|
||||
Type string `json:"type" binding:"Required"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Settings *simplejson.Json `json:"settings" binding:"Required"`
|
||||
Id int64 `json:"id" binding:"Required"`
|
||||
Name string `json:"name" binding:"Required"`
|
||||
Type string `json:"type" binding:"Required"`
|
||||
NotifyOnce string `json:"notifyOnce" binding:"Required"`
|
||||
Frequency string `json:"frequency"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Settings *simplejson.Json `json:"settings" binding:"Required"`
|
||||
|
||||
OrgId int64 `json:"-"`
|
||||
Result *AlertNotification
|
||||
@@ -63,3 +69,34 @@ type GetAllAlertNotificationsQuery struct {
|
||||
|
||||
Result []*AlertNotification
|
||||
}
|
||||
|
||||
type NotificationJournal struct {
|
||||
Id int64
|
||||
OrgId int64
|
||||
AlertId int64
|
||||
NotifierId int64
|
||||
SentAt time.Time
|
||||
Success bool
|
||||
}
|
||||
|
||||
type RecordNotificationJournalCommand struct {
|
||||
OrgId int64
|
||||
AlertId int64
|
||||
NotifierId int64
|
||||
SentAt time.Time
|
||||
Success bool
|
||||
}
|
||||
|
||||
type GetLatestNotificationQuery struct {
|
||||
OrgId int64
|
||||
AlertId int64
|
||||
NotifierId int64
|
||||
|
||||
Result *NotificationJournal
|
||||
}
|
||||
|
||||
type CleanNotificationJournalCommand struct {
|
||||
OrgId int64
|
||||
AlertId int64
|
||||
NotifierId int64
|
||||
}
|
||||
|
||||
@@ -143,3 +143,18 @@ func (c *EvalContext) GetNewState() m.AlertStateType {
|
||||
|
||||
return m.AlertStateOK
|
||||
}
|
||||
|
||||
func (c *EvalContext) LastNotify(notifierId int64) *time.Time {
|
||||
cmd := &m.GetLatestNotificationQuery{
|
||||
OrgId: c.Rule.OrgId,
|
||||
AlertId: c.Rule.Id,
|
||||
NotifierId: notifierId,
|
||||
}
|
||||
if err := bus.Dispatch(cmd); err != nil {
|
||||
c.log.Warn("Could not determine last time alert",
|
||||
c.Rule.Name, "notified")
|
||||
return nil
|
||||
}
|
||||
|
||||
return &cmd.Result.SentAt
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@ func (e *DashAlertExtractor) getAlertFromPanels(jsonWithPanels *simplejson.Json,
|
||||
Handler: jsonAlert.Get("handler").MustInt64(),
|
||||
Message: jsonAlert.Get("message").MustString(),
|
||||
Frequency: frequency,
|
||||
NotifyOnce: jsonAlert.Get("notifyOnce").MustBool(),
|
||||
NotifyFreq: jsonAlert.Get("notifyFrequency").MustUint64(),
|
||||
}
|
||||
|
||||
for _, condition := range jsonAlert.Get("conditions").MustArray() {
|
||||
|
||||
@@ -19,6 +19,8 @@ type Notifier interface {
|
||||
|
||||
GetNotifierId() int64
|
||||
GetIsDefault() bool
|
||||
GetNotifyOnce() bool
|
||||
GetFrequency() time.Duration
|
||||
}
|
||||
|
||||
type NotifierSlice []Notifier
|
||||
|
||||
@@ -66,7 +66,17 @@ func (n *notificationService) sendNotifications(context *EvalContext, notifiers
|
||||
not := notifier //avoid updating scope variable in go routine
|
||||
n.log.Debug("Sending notification", "type", not.GetType(), "id", not.GetNotifierId(), "isDefault", not.GetIsDefault())
|
||||
metrics.M_Alerting_Notification_Sent.WithLabelValues(not.GetType()).Inc()
|
||||
g.Go(func() error { return not.Notify(context) })
|
||||
g.Go(func() error {
|
||||
success := not.Notify(context) == nil
|
||||
cmd := &m.RecordNotificationJournalCommand{
|
||||
OrgId: context.Rule.OrgId,
|
||||
AlertId: context.Rule.Id,
|
||||
NotifierId: not.GetNotifierId(),
|
||||
SentAt: time.Now(),
|
||||
Success: success,
|
||||
}
|
||||
return bus.Dispatch(cmd)
|
||||
})
|
||||
}
|
||||
|
||||
return g.Wait()
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewAlertmanagerNotifier(model *m.AlertNotification) (alerting.Notifier, err
|
||||
}
|
||||
|
||||
return &AlertmanagerNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
log: log.New("alerting.notifier.prometheus-alertmanager"),
|
||||
}, nil
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
@@ -12,9 +14,11 @@ type NotifierBase struct {
|
||||
Id int64
|
||||
IsDeault bool
|
||||
UploadImage bool
|
||||
NotifyOnce bool
|
||||
Frequency time.Duration
|
||||
}
|
||||
|
||||
func NewNotifierBase(id int64, isDefault bool, name, notifierType string, model *simplejson.Json) NotifierBase {
|
||||
func NewNotifierBase(id int64, isDefault bool, name, notifierType string, notifyOnce bool, frequency time.Duration, model *simplejson.Json) NotifierBase {
|
||||
uploadImage := true
|
||||
value, exist := model.CheckGet("uploadImage")
|
||||
if exist {
|
||||
@@ -27,15 +31,17 @@ func NewNotifierBase(id int64, isDefault bool, name, notifierType string, model
|
||||
IsDeault: isDefault,
|
||||
Type: notifierType,
|
||||
UploadImage: uploadImage,
|
||||
NotifyOnce: notifyOnce,
|
||||
Frequency: frequency,
|
||||
}
|
||||
}
|
||||
|
||||
func defaultShouldNotify(context *alerting.EvalContext) bool {
|
||||
func defaultShouldNotify(context *alerting.EvalContext, notifyOnce bool, frequency time.Duration, lastNotify *time.Time) bool {
|
||||
// Only notify on state change.
|
||||
if context.PrevAlertState == context.Rule.State && context.Rule.NotifyOnce {
|
||||
if context.PrevAlertState == context.Rule.State && notifyOnce {
|
||||
return false
|
||||
}
|
||||
if !context.Rule.NotifyOnce && context.Rule.NotifyEval != 0 {
|
||||
if !notifyOnce && lastNotify != nil && lastNotify.Add(frequency).After(time.Now()) {
|
||||
return false
|
||||
}
|
||||
// Do not notify when we become OK for the first time.
|
||||
@@ -46,7 +52,8 @@ func defaultShouldNotify(context *alerting.EvalContext) bool {
|
||||
}
|
||||
|
||||
func (n *NotifierBase) ShouldNotify(context *alerting.EvalContext) bool {
|
||||
return defaultShouldNotify(context)
|
||||
lastNotify := context.LastNotify(n.Id)
|
||||
return defaultShouldNotify(context, n.NotifyOnce, n.Frequency, lastNotify)
|
||||
}
|
||||
|
||||
func (n *NotifierBase) GetType() string {
|
||||
@@ -64,3 +71,11 @@ func (n *NotifierBase) GetNotifierId() int64 {
|
||||
func (n *NotifierBase) GetIsDefault() bool {
|
||||
return n.IsDeault
|
||||
}
|
||||
|
||||
func (n *NotifierBase) GetNotifyOnce() bool {
|
||||
return n.NotifyOnce
|
||||
}
|
||||
|
||||
func (n *NotifierBase) GetFrequency() time.Duration {
|
||||
return n.Frequency
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
||||
}
|
||||
|
||||
return &DingDingNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
log: log.New("alerting.notifier.dingding"),
|
||||
}, nil
|
||||
|
||||
@@ -39,7 +39,7 @@ func NewDiscordNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &DiscordNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
WebhookURL: url,
|
||||
log: log.New("alerting.notifier.discord"),
|
||||
}, nil
|
||||
|
||||
@@ -52,7 +52,7 @@ func NewEmailNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
})
|
||||
|
||||
return &EmailNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Addresses: addresses,
|
||||
log: log.New("alerting.notifier.email"),
|
||||
}, nil
|
||||
|
||||
@@ -59,7 +59,7 @@ func NewHipChatNotifier(model *models.AlertNotification) (alerting.Notifier, err
|
||||
roomId := model.Settings.Get("roomid").MustString()
|
||||
|
||||
return &HipChatNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
ApiKey: apikey,
|
||||
RoomId: roomId,
|
||||
|
||||
@@ -43,7 +43,7 @@ func NewKafkaNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &KafkaNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Endpoint: endpoint,
|
||||
Topic: topic,
|
||||
log: log.New("alerting.notifier.kafka"),
|
||||
|
||||
@@ -39,7 +39,7 @@ func NewLINENotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &LineNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Token: token,
|
||||
log: log.New("alerting.notifier.line"),
|
||||
}, nil
|
||||
|
||||
@@ -56,7 +56,7 @@ func NewOpsGenieNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
||||
}
|
||||
|
||||
return &OpsGenieNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
ApiKey: apiKey,
|
||||
ApiUrl: apiUrl,
|
||||
AutoClose: autoClose,
|
||||
|
||||
@@ -51,7 +51,7 @@ func NewPagerdutyNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
||||
}
|
||||
|
||||
return &PagerdutyNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Key: key,
|
||||
AutoResolve: autoResolve,
|
||||
log: log.New("alerting.notifier.pagerduty"),
|
||||
|
||||
@@ -99,7 +99,7 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
||||
return nil, alerting.ValidationError{Reason: "API token not given"}
|
||||
}
|
||||
return &PushoverNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
UserKey: userKey,
|
||||
ApiToken: apiToken,
|
||||
Priority: priority,
|
||||
|
||||
@@ -51,7 +51,7 @@ func NewSensuNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &SensuNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
User: model.Settings.Get("username").MustString(),
|
||||
Source: model.Settings.Get("source").MustString(),
|
||||
|
||||
@@ -78,7 +78,7 @@ func NewSlackNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
uploadImage := model.Settings.Get("uploadImage").MustBool(true)
|
||||
|
||||
return &SlackNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
Recipient: recipient,
|
||||
Mention: mention,
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewTeamsNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &TeamsNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
log: log.New("alerting.notifier.teams"),
|
||||
}, nil
|
||||
|
||||
@@ -78,7 +78,7 @@ func NewTelegramNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
||||
}
|
||||
|
||||
return &TelegramNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
BotToken: botToken,
|
||||
ChatID: chatId,
|
||||
UploadImage: uploadImage,
|
||||
|
||||
@@ -106,7 +106,7 @@ func NewThreemaNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &ThreemaNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
GatewayID: gatewayID,
|
||||
RecipientID: recipientID,
|
||||
APISecret: apiSecret,
|
||||
|
||||
@@ -51,7 +51,7 @@ func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, e
|
||||
}
|
||||
|
||||
return &VictoropsNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
URL: url,
|
||||
AutoResolve: autoResolve,
|
||||
log: log.New("alerting.notifier.victorops"),
|
||||
|
||||
@@ -47,7 +47,7 @@ func NewWebHookNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
|
||||
}
|
||||
|
||||
return &WebhookNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings),
|
||||
Url: url,
|
||||
User: model.Settings.Get("username").MustString(),
|
||||
Password: model.Settings.Get("password").MustString(),
|
||||
|
||||
@@ -88,7 +88,6 @@ func (handler *DefaultResultHandler) Handle(evalContext *EvalContext) error {
|
||||
}
|
||||
}
|
||||
|
||||
bus.Dispatch(&m.IncAlertEvalCommand{AlertId: evalContext.Rule.Id})
|
||||
handler.notifier.SendIfNeeded(evalContext)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -23,9 +23,6 @@ type Rule struct {
|
||||
State m.AlertStateType
|
||||
Conditions []Condition
|
||||
Notifications []int64
|
||||
NotifyOnce bool
|
||||
NotifyFreq uint64
|
||||
NotifyEval uint64
|
||||
}
|
||||
|
||||
type ValidationError struct {
|
||||
@@ -100,9 +97,6 @@ func NewRuleFromDBAlert(ruleDef *m.Alert) (*Rule, error) {
|
||||
model.Name = ruleDef.Name
|
||||
model.Message = ruleDef.Message
|
||||
model.Frequency = ruleDef.Frequency
|
||||
model.NotifyOnce = ruleDef.NotifyOnce
|
||||
model.NotifyFreq = ruleDef.NotifyFreq
|
||||
model.NotifyEval = ruleDef.NotifyEval
|
||||
model.State = ruleDef.State
|
||||
model.NoDataState = m.NoDataOption(ruleDef.Settings.Get("noDataState").MustString("no_data"))
|
||||
model.ExecutionErrorState = m.ExecutionErrorOption(ruleDef.Settings.Get("executionErrorState").MustString("alerting"))
|
||||
|
||||
@@ -22,7 +22,6 @@ func init() {
|
||||
bus.AddHandler("sql", GetAlertStatesForDashboard)
|
||||
bus.AddHandler("sql", PauseAlert)
|
||||
bus.AddHandler("sql", PauseAllAlerts)
|
||||
bus.AddHandler("sql", IncAlertEval)
|
||||
}
|
||||
|
||||
func GetAlertById(query *m.GetAlertByIdQuery) error {
|
||||
@@ -189,7 +188,7 @@ func updateAlerts(existingAlerts []*m.Alert, cmd *m.SaveAlertsCommand, sess *DBS
|
||||
if alertToUpdate.ContainsUpdates(alert) {
|
||||
alert.Updated = timeNow()
|
||||
alert.State = alertToUpdate.State
|
||||
sess.MustCols("message", "notify_freq", "notify_once")
|
||||
sess.MustCols("message")
|
||||
_, err := sess.Id(alert.Id).Update(alert)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -344,22 +343,3 @@ func GetAlertStatesForDashboard(query *m.GetAlertStatesForDashboardQuery) error
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func IncAlertEval(cmd *m.IncAlertEvalCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
alert := m.Alert{}
|
||||
|
||||
if _, err := sess.Id(cmd.AlertId).Get(&alert); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
alert.NotifyEval = (alert.NotifyEval + 1) % alert.NotifyFreq
|
||||
|
||||
sess.MustCols("notify_eval")
|
||||
if _, err := sess.Id(cmd.AlertId).Update(alert); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ func init() {
|
||||
bus.AddHandler("sql", DeleteAlertNotification)
|
||||
bus.AddHandler("sql", GetAlertNotificationsToSend)
|
||||
bus.AddHandler("sql", GetAllAlertNotifications)
|
||||
bus.AddHandler("sql", RecordNotificationJournal)
|
||||
bus.AddHandler("sql", GetLatestNotification)
|
||||
bus.AddHandler("sql", CleanNotificationJournal)
|
||||
}
|
||||
|
||||
func DeleteAlertNotification(cmd *m.DeleteAlertNotificationCommand) error {
|
||||
@@ -138,13 +141,15 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error
|
||||
}
|
||||
|
||||
alertNotification := &m.AlertNotification{
|
||||
OrgId: cmd.OrgId,
|
||||
Name: cmd.Name,
|
||||
Type: cmd.Type,
|
||||
Settings: cmd.Settings,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
IsDefault: cmd.IsDefault,
|
||||
OrgId: cmd.OrgId,
|
||||
Name: cmd.Name,
|
||||
Type: cmd.Type,
|
||||
Settings: cmd.Settings,
|
||||
NotifyOnce: cmd.NotifyOnce,
|
||||
Frequency: cmd.Frequency,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
IsDefault: cmd.IsDefault,
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(alertNotification); err != nil {
|
||||
@@ -192,3 +197,42 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func RecordNotificationJournal(cmd *m.RecordNotificationJournalCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
journalEntry := &m.NotificationJournal{
|
||||
OrgId: cmd.OrgId,
|
||||
AlertId: cmd.AlertId,
|
||||
NotifierId: cmd.NotifierId,
|
||||
SentAt: cmd.SentAt,
|
||||
Success: cmd.Success,
|
||||
}
|
||||
|
||||
if _, err := sess.Insert(journalEntry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func GetLatestNotification(cmd *m.GetLatestNotificationQuery) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
notificationJournal := &m.NotificationJournal{}
|
||||
_, err := sess.OrderBy("notification_journal.sent_at").Desc().Where("notification_journal.org_id = ? AND notification_journal.alert_id = ? AND notification_journal.notifier_id = ?", cmd.OrgId, cmd.AlertId, cmd.NotifierId).Get(notificationJournal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Result = notificationJournal
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CleanNotificationJournal(cmd *m.CleanNotificationJournalCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
sql := "DELETE FROM notification_journal WHERE notification_journal.org_id = ? AND notification_journal.alert_id = ? AND notification_journal.notifier_id = ?"
|
||||
_, err := sess.Exec(sql, cmd.OrgId, cmd.AlertId, cmd.NotifierId)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -29,9 +29,6 @@ func addAlertMigrations(mg *Migrator) {
|
||||
{Name: "state_changes", Type: DB_Int, Nullable: false},
|
||||
{Name: "created", Type: DB_DateTime, Nullable: false},
|
||||
{Name: "updated", Type: DB_DateTime, Nullable: false},
|
||||
{Name: "notify_once", Type: DB_Bool, Nullable: false},
|
||||
{Name: "notify_freq", Type: DB_Int, Nullable: false},
|
||||
{Name: "notify_eval", Type: DB_Int, Nullable: false},
|
||||
},
|
||||
Indices: []*Index{
|
||||
{Cols: []string{"org_id", "id"}, Type: IndexType},
|
||||
@@ -68,8 +65,32 @@ func addAlertMigrations(mg *Migrator) {
|
||||
mg.AddMigration("Add column is_default", NewAddColumnMigration(alert_notification, &Column{
|
||||
Name: "is_default", Type: DB_Bool, Nullable: false, Default: "0",
|
||||
}))
|
||||
mg.AddMigration("Add column frequency", NewAddColumnMigration(alert_notification, &Column{
|
||||
Name: "frequency", Type: DB_BigInt, Nullable: true,
|
||||
}))
|
||||
mg.AddMigration("Add column notify_once", NewAddColumnMigration(alert_notification, &Column{
|
||||
Name: "notify_once", Type: DB_Bool, Nullable: false, Default: "1",
|
||||
}))
|
||||
mg.AddMigration("add index alert_notification org_id & name", NewAddIndexMigration(alert_notification, alert_notification.Indices[0]))
|
||||
|
||||
notification_journal := Table{
|
||||
Name: "notification_journal",
|
||||
Columns: []*Column{
|
||||
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
||||
{Name: "org_id", Type: DB_BigInt, Nullable: false},
|
||||
{Name: "alert_id", Type: DB_BigInt, Nullable: false},
|
||||
{Name: "notifier_id", Type: DB_BigInt, Nullable: false},
|
||||
{Name: "sent_at", Type: DB_DateTime, Nullable: false},
|
||||
{Name: "success", Type: DB_Bool, Nullable: false},
|
||||
},
|
||||
Indices: []*Index{
|
||||
{Cols: []string{"org_id", "alert_id", "notifier_id"}, Type: IndexType},
|
||||
},
|
||||
}
|
||||
|
||||
mg.AddMigration("create notification_journal table v1", NewAddTableMigration(notification_journal))
|
||||
mg.AddMigration("add index notification_journal org_id & alert_id & notifier_id", NewAddIndexMigration(notification_journal, notification_journal.Indices[0]))
|
||||
|
||||
mg.AddMigration("Update alert table charset", NewTableCharsetMigration("alert", []*Column{
|
||||
{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
|
||||
{Name: "message", Type: DB_Text, Nullable: false},
|
||||
|
||||
@@ -167,9 +167,6 @@ export class AlertTabCtrl {
|
||||
alert.noDataState = alert.noDataState || 'no_data';
|
||||
alert.executionErrorState = alert.executionErrorState || 'alerting';
|
||||
alert.frequency = alert.frequency || '60s';
|
||||
alert.notifyFrequency = alert.notifyFrequency || 10;
|
||||
alert.notifyOnce = alert.notifyOnce == null ? true : alert.notifyOnce;
|
||||
alert.frequency = alert.frequency || '60s';
|
||||
alert.handler = alert.handler || 1;
|
||||
alert.notifications = alert.notifications || [];
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ export class AlertNotificationEditCtrl {
|
||||
model: any;
|
||||
defaults: any = {
|
||||
type: 'email',
|
||||
notifyOnce: true,
|
||||
settings: {
|
||||
httpMethod: 'POST',
|
||||
autoResolve: true,
|
||||
@@ -102,6 +103,7 @@ export class AlertNotificationEditCtrl {
|
||||
var payload = {
|
||||
name: this.model.name,
|
||||
type: this.model.type,
|
||||
frequency: this.model.frequency,
|
||||
settings: this.model.settings,
|
||||
};
|
||||
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
<input type="text" class="gf-form-input width-20" ng-model="ctrl.alert.name">
|
||||
<span class="gf-form-label">Evaluate every</span>
|
||||
<input class="gf-form-input max-width-5" type="text" ng-model="ctrl.alert.frequency"></input>
|
||||
<a class="gf-form-label" ng-click="ctrl.alert.notifyOnce = !ctrl.alert.notifyOnce;">{{ ctrl.alert.notifyOnce ? 'Notify on state change' : 'Notify every' }}</a>
|
||||
<input class="gf-form-input max-width-5" type="number" ng-model="ctrl.alert.notifyFrequency" ng-hide="ctrl.alert.notifyOnce"></input>
|
||||
<span class="gf-form-label" ng-hide="ctrl.alert.notifyOnce">evaluations</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<a class="gf-form-label width-12" ng-click="ctrl.model.notifyOnce = !ctrl.model.notifyOnce;">{{ ctrl.model.notifyOnce ? 'Notify on state change' : 'Notify at most every' }}</a>
|
||||
<input class="gf-form-input max-width-10" type="number" required ng-model="ctrl.model.frequency" required ng-hide="ctrl.model.notifyOnce"></input>
|
||||
<span class="gf-form-label max-width-5" ng-hide="ctrl.model.notifyOnce">seconds</span>
|
||||
</div>
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Send on all alerts"
|
||||
|
||||
Reference in New Issue
Block a user