From 488b42377bf705b2b44b2e93b4c351a577c53e55 Mon Sep 17 00:00:00 2001 From: bergquist Date: Thu, 23 Jun 2016 11:03:27 +0200 Subject: [PATCH] feat(alerting): update state if not been updated for 15min --- pkg/api/alerting.go | 1 + pkg/models/alert_state.go | 8 ++++++++ pkg/services/alerting/engine.go | 25 +++++++++++++++++++---- pkg/services/sqlstore/alert_state.go | 30 +++++++++++++++++++--------- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/pkg/api/alerting.go b/pkg/api/alerting.go index 6f59527fec9..4df0b6a79e3 100644 --- a/pkg/api/alerting.go +++ b/pkg/api/alerting.go @@ -140,6 +140,7 @@ func GetAlertStates(c *middleware.Context) Response { // PUT /api/alerts/events/:id func PutAlertState(c *middleware.Context, cmd models.UpdateAlertStateCommand) Response { cmd.AlertId = c.ParamsInt64(":alertId") + cmd.OrgId = c.OrgId query := models.GetAlertByIdQuery{Id: cmd.AlertId} if err := bus.Dispatch(&query); err != nil { diff --git a/pkg/models/alert_state.go b/pkg/models/alert_state.go index 30d442ed625..ae29b7d8a77 100644 --- a/pkg/models/alert_state.go +++ b/pkg/models/alert_state.go @@ -28,6 +28,7 @@ func (this *UpdateAlertStateCommand) IsValidState() bool { type UpdateAlertStateCommand struct { AlertId int64 `json:"alertId" binding:"Required"` + OrgId int64 `json:"orgId" binding:"Required"` NewState string `json:"newState" binding:"Required"` Info string `json:"info"` @@ -42,3 +43,10 @@ type GetAlertsStateQuery struct { Result *[]AlertState } + +type GetLastAlertStateQuery struct { + AlertId int64 + OrgId int64 + + Result *AlertState +} diff --git a/pkg/services/alerting/engine.go b/pkg/services/alerting/engine.go index a840af70eb5..100ea5ae0b3 100644 --- a/pkg/services/alerting/engine.go +++ b/pkg/services/alerting/engine.go @@ -143,14 +143,12 @@ func (e *Engine) resultHandler() { } func (e *Engine) reactToState(result *AlertResult) { - query := &m.GetAlertByIdQuery{Id: result.AlertJob.Rule.Id} - bus.Dispatch(query) - - if query.Result.ShouldUpdateState(result.State) { + if shouldUpdateState(result) { cmd := &m.UpdateAlertStateCommand{ AlertId: result.AlertJob.Rule.Id, NewState: result.State, Info: result.Description, + OrgId: result.AlertJob.Rule.OrgId, } if err := bus.Dispatch(cmd); err != nil { @@ -161,3 +159,22 @@ func (e *Engine) reactToState(result *AlertResult) { e.notifier.Notify(result) } } + +func shouldUpdateState(result *AlertResult) bool { + query := &m.GetLastAlertStateQuery{ + AlertId: result.AlertJob.Rule.Id, + OrgId: result.AlertJob.Rule.OrgId, + } + + if err := bus.Dispatch(query); err != nil { + log.Error2("Failed to read last alert state", "error", err) + return false + } + + now := time.Now() + noEarlierState := query.Result == nil + olderThen15Min := query.Result.Created.Before(now.Add(time.Minute * -15)) + changedState := query.Result.NewState != result.State + + return noEarlierState || changedState || olderThen15Min +} diff --git a/pkg/services/sqlstore/alert_state.go b/pkg/services/sqlstore/alert_state.go index 1c64ef976bd..d2453f0cb26 100644 --- a/pkg/services/sqlstore/alert_state.go +++ b/pkg/services/sqlstore/alert_state.go @@ -12,6 +12,23 @@ import ( func init() { bus.AddHandler("sql", SetNewAlertState) bus.AddHandler("sql", GetAlertStateLogByAlertId) + bus.AddHandler("sql", GetLastAlertStateQuery) +} + +func GetLastAlertStateQuery(cmd *m.GetLastAlertStateQuery) error { + states := make([]m.AlertState, 0) + + if err := x.Where("alert_id = ? and org_id = ? ", cmd.AlertId, cmd.OrgId).Desc("created").Find(&states); err != nil { + return err + } + + if len(states) == 0 { + cmd.Result = nil + return fmt.Errorf("invalid amount of alertstates. Expected 1 got %v", len(states)) + } + + cmd.Result = &states[0] + return nil } func SetNewAlertState(cmd *m.UpdateAlertStateCommand) error { @@ -30,17 +47,12 @@ func SetNewAlertState(cmd *m.UpdateAlertStateCommand) error { return fmt.Errorf("Could not find alert") } - if alert.State == cmd.NewState { - cmd.Result = &m.Alert{} - return nil - } - alert.State = cmd.NewState sess.Id(alert.Id).Update(&alert) alertState := m.AlertState{ AlertId: cmd.AlertId, - OrgId: cmd.AlertId, + OrgId: cmd.OrgId, NewState: cmd.NewState, Info: cmd.Info, Created: time.Now(), @@ -54,12 +66,12 @@ func SetNewAlertState(cmd *m.UpdateAlertStateCommand) error { } func GetAlertStateLogByAlertId(cmd *m.GetAlertsStateQuery) error { - alertLogs := make([]m.AlertState, 0) + states := make([]m.AlertState, 0) - if err := x.Where("alert_id = ?", cmd.AlertId).Desc("created").Find(&alertLogs); err != nil { + if err := x.Where("alert_id = ?", cmd.AlertId).Desc("created").Find(&states); err != nil { return err } - cmd.Result = &alertLogs + cmd.Result = &states return nil }