mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
reminder: uses UpdatedAt to track state changes.
This commit is contained in:
@@ -19,6 +19,7 @@ type AlertNotificationStateType string
|
||||
var (
|
||||
AlertNotificationStatePending = AlertNotificationStateType("pending")
|
||||
AlertNotificationStateCompleted = AlertNotificationStateType("completed")
|
||||
AlertNotificationStateUnknown = AlertNotificationStateType("unknown")
|
||||
)
|
||||
|
||||
type AlertNotification struct {
|
||||
@@ -86,14 +87,14 @@ type GetAllAlertNotificationsQuery struct {
|
||||
}
|
||||
|
||||
type AlertNotificationState struct {
|
||||
Id int64
|
||||
OrgId int64
|
||||
AlertId int64
|
||||
NotifierId int64
|
||||
SentAt int64
|
||||
State AlertNotificationStateType
|
||||
Version int64
|
||||
UpdatedAt int64
|
||||
Id int64
|
||||
OrgId int64
|
||||
AlertId int64
|
||||
NotifierId int64
|
||||
State AlertNotificationStateType
|
||||
Version int64
|
||||
UpdatedAt int64
|
||||
AlertRuleStateUpdatedVersion int64
|
||||
}
|
||||
|
||||
type SetAlertNotificationStateToPendingCommand struct {
|
||||
|
@@ -68,7 +68,7 @@ func (n *notificationService) sendAndMarkAsComplete(evalContext *EvalContext, no
|
||||
if err != nil {
|
||||
n.log.Error("failed to send notification", "id", not.GetNotifierId())
|
||||
} else {
|
||||
notifierState.state.SentAt = time.Now().UTC().Unix()
|
||||
notifierState.state.UpdatedAt = time.Now().UTC().Unix()
|
||||
}
|
||||
|
||||
if evalContext.IsTestRun {
|
||||
@@ -185,7 +185,7 @@ func (n *notificationService) getNeededNotifiers(orgId int64, notificationIds []
|
||||
|
||||
err = bus.DispatchCtx(evalContext.Ctx, query)
|
||||
if err != nil {
|
||||
n.log.Error("Could not get notification state.", "notifier", notification.Id)
|
||||
n.log.Error("Could not get notification state.", "notifier", notification.Id, "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@@ -53,8 +53,8 @@ func defaultShouldNotify(context *alerting.EvalContext, sendReminder bool, frequ
|
||||
|
||||
if context.PrevAlertState == context.Rule.State && sendReminder {
|
||||
// Do not notify if interval has not elapsed
|
||||
lastNotify := time.Unix(notificationState.SentAt, 0)
|
||||
if notificationState.SentAt != 0 && lastNotify.Add(frequency).After(time.Now()) {
|
||||
lastNotify := time.Unix(notificationState.UpdatedAt, 0)
|
||||
if notificationState.UpdatedAt != 0 && lastNotify.Add(frequency).After(time.Now()) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@@ -84,7 +84,7 @@ func TestShouldSendAlertNotification(t *testing.T) {
|
||||
prevState: m.AlertStateAlerting,
|
||||
frequency: time.Minute * 10,
|
||||
sendReminder: true,
|
||||
state: &m.AlertNotificationState{SentAt: tnow.Add(-time.Minute).Unix()},
|
||||
state: &m.AlertNotificationState{UpdatedAt: tnow.Add(-time.Minute).Unix()},
|
||||
|
||||
expect: true,
|
||||
},
|
||||
@@ -104,7 +104,7 @@ func TestShouldSendAlertNotification(t *testing.T) {
|
||||
prevState: m.AlertStateAlerting,
|
||||
frequency: time.Minute * 10,
|
||||
sendReminder: true,
|
||||
state: &m.AlertNotificationState{SentAt: tnow.Add(-time.Minute).Unix()},
|
||||
state: &m.AlertNotificationState{UpdatedAt: tnow.Add(-time.Minute).Unix()},
|
||||
|
||||
expect: false,
|
||||
},
|
||||
@@ -114,7 +114,7 @@ func TestShouldSendAlertNotification(t *testing.T) {
|
||||
prevState: m.AlertStateAlerting,
|
||||
frequency: time.Minute * 10,
|
||||
sendReminder: true,
|
||||
state: &m.AlertNotificationState{SentAt: tnow.Add(-11 * time.Minute).Unix()},
|
||||
state: &m.AlertNotificationState{UpdatedAt: tnow.Add(-11 * time.Minute).Unix()},
|
||||
|
||||
expect: true,
|
||||
},
|
||||
|
@@ -102,6 +102,7 @@ func NewRuleFromDBAlert(ruleDef *m.Alert) (*Rule, error) {
|
||||
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"))
|
||||
model.StateChanges = ruleDef.StateChanges
|
||||
|
||||
for _, v := range ruleDef.Settings.Get("notifications").MustArray() {
|
||||
jsonModel := simplejson.NewFromAny(v)
|
||||
|
@@ -249,12 +249,11 @@ func SetAlertNotificationStateToCompleteCommand(ctx context.Context, cmd *m.SetA
|
||||
sql := `UPDATE alert_notification_state SET
|
||||
state = ?,
|
||||
version = ?,
|
||||
sent_at = ?,
|
||||
updated_at = ?
|
||||
WHERE
|
||||
id = ?`
|
||||
|
||||
_, err := sess.Exec(sql, cmd.State.State, cmd.State.Version, cmd.State.SentAt, timeNow().Unix(), cmd.State.Id)
|
||||
_, err := sess.Exec(sql, cmd.State.State, cmd.State.Version, timeNow().Unix(), cmd.State.Id)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -325,7 +324,7 @@ func GetAlertNotificationState(ctx context.Context, cmd *m.GetNotificationStateQ
|
||||
OrgId: cmd.OrgId,
|
||||
AlertId: cmd.AlertId,
|
||||
NotifierId: cmd.NotifierId,
|
||||
State: "unknown",
|
||||
State: m.AlertNotificationStateUnknown,
|
||||
UpdatedAt: timeNow().Unix(),
|
||||
}
|
||||
|
||||
@@ -354,10 +353,9 @@ func GetAlertNotificationState(ctx context.Context, cmd *m.GetNotificationStateQ
|
||||
}
|
||||
|
||||
func getAlertNotificationState(sess *DBSession, cmd *m.GetNotificationStateQuery, nj *m.AlertNotificationState) (bool, error) {
|
||||
exist, err := sess.
|
||||
return sess.
|
||||
Where("alert_notification_state.org_id = ?", cmd.OrgId).
|
||||
Where("alert_notification_state.alert_id = ?", cmd.AlertId).
|
||||
Where("alert_notification_state.notifier_id = ?", cmd.NotifierId).
|
||||
Get(nj)
|
||||
return exist, err
|
||||
}
|
||||
|
@@ -117,10 +117,10 @@ func addAlertMigrations(mg *Migrator) {
|
||||
{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_BigInt, Nullable: false},
|
||||
{Name: "state", Type: DB_NVarchar, Length: 50, Nullable: false},
|
||||
{Name: "version", Type: DB_BigInt, Nullable: false},
|
||||
{Name: "updated_at", Type: DB_BigInt, Nullable: false},
|
||||
{Name: "alert_rule_state_updated_version", Type: DB_BigInt, Nullable: false},
|
||||
},
|
||||
Indices: []*Index{
|
||||
{Cols: []string{"org_id", "alert_id", "notifier_id"}, Type: UniqueIndex},
|
||||
@@ -130,8 +130,4 @@ func addAlertMigrations(mg *Migrator) {
|
||||
mg.AddMigration("create alert_notification_state table v1", NewAddTableMigration(alert_notification_state))
|
||||
mg.AddMigration("add index alert_notification_state org_id & alert_id & notifier_id",
|
||||
NewAddIndexMigration(alert_notification_state, alert_notification_state.Indices[0]))
|
||||
|
||||
mg.AddMigration("Add alert_rule_state_updated_version to alert_notification_state", NewAddColumnMigration(alert_notification_state, &Column{
|
||||
Name: "alert_rule_state_updated_version", Type: DB_BigInt, Nullable: true,
|
||||
}))
|
||||
}
|
||||
|
Reference in New Issue
Block a user