Commit d25284a3 by bergquist

introduce state `unknown` for rules that have not been evaluated yet

parent 6f748d8a
...@@ -291,7 +291,7 @@ func PauseAlert(c *m.ReqContext, dto dtos.PauseAlertCommand) Response { ...@@ -291,7 +291,7 @@ func PauseAlert(c *m.ReqContext, dto dtos.PauseAlertCommand) Response {
return Error(500, "", err) return Error(500, "", err)
} }
var response m.AlertStateType = m.AlertStatePending var response m.AlertStateType = m.AlertStateUnknown
pausedState := "un-paused" pausedState := "un-paused"
if cmd.Paused { if cmd.Paused {
response = m.AlertStatePaused response = m.AlertStatePaused
......
...@@ -19,6 +19,7 @@ const ( ...@@ -19,6 +19,7 @@ const (
AlertStateAlerting AlertStateType = "alerting" AlertStateAlerting AlertStateType = "alerting"
AlertStateOK AlertStateType = "ok" AlertStateOK AlertStateType = "ok"
AlertStatePending AlertStateType = "pending" AlertStatePending AlertStateType = "pending"
AlertStateUnknown AlertStateType = "unknown"
) )
const ( const (
...@@ -39,7 +40,12 @@ var ( ...@@ -39,7 +40,12 @@ var (
) )
func (s AlertStateType) IsValid() bool { func (s AlertStateType) IsValid() bool {
return s == AlertStateOK || s == AlertStateNoData || s == AlertStatePaused || s == AlertStatePending return s == AlertStateOK ||
s == AlertStateNoData ||
s == AlertStatePaused ||
s == AlertStatePending ||
s == AlertStateAlerting ||
s == AlertStateUnknown
} }
func (s NoDataOption) IsValid() bool { func (s NoDataOption) IsValid() bool {
......
...@@ -68,6 +68,11 @@ func (c *EvalContext) GetStateModel() *StateDescription { ...@@ -68,6 +68,11 @@ func (c *EvalContext) GetStateModel() *StateDescription {
Color: "#D63232", Color: "#D63232",
Text: "Alerting", Text: "Alerting",
} }
case m.AlertStateUnknown:
return &StateDescription{
Color: "888888",
Text: "Unknown",
}
default: default:
panic("Unknown rule state for alert notifications " + c.Rule.State) panic("Unknown rule state for alert notifications " + c.Rule.State)
} }
......
...@@ -67,6 +67,11 @@ func (n *NotifierBase) ShouldNotify(ctx context.Context, context *alerting.EvalC ...@@ -67,6 +67,11 @@ func (n *NotifierBase) ShouldNotify(ctx context.Context, context *alerting.EvalC
} }
// Do not notify when we become OK for the first time. // Do not notify when we become OK for the first time.
if context.PrevAlertState == models.AlertStateUnknown && context.Rule.State == models.AlertStateOK {
return false
}
// Do not notify when we become OK from pending
if context.PrevAlertState == models.AlertStatePending && context.Rule.State == models.AlertStateOK { if context.PrevAlertState == models.AlertStatePending && context.Rule.State == models.AlertStateOK {
return false return false
} }
......
...@@ -134,6 +134,22 @@ func TestShouldSendAlertNotification(t *testing.T) { ...@@ -134,6 +134,22 @@ func TestShouldSendAlertNotification(t *testing.T) {
expect: true, expect: true,
}, },
{
name: "unknown -> ok",
prevState: m.AlertStateUnknown,
newState: m.AlertStateOK,
state: &m.AlertNotificationState{},
expect: false,
},
{
name: "unknown -> alerting",
prevState: m.AlertStateUnknown,
newState: m.AlertStateAlerting,
state: &m.AlertNotificationState{},
expect: true,
},
} }
for _, tc := range tcs { for _, tc := range tcs {
......
...@@ -205,7 +205,7 @@ func updateAlerts(existingAlerts []*m.Alert, cmd *m.SaveAlertsCommand, sess *DBS ...@@ -205,7 +205,7 @@ func updateAlerts(existingAlerts []*m.Alert, cmd *m.SaveAlertsCommand, sess *DBS
} else { } else {
alert.Updated = timeNow() alert.Updated = timeNow()
alert.Created = timeNow() alert.Created = timeNow()
alert.State = m.AlertStatePending alert.State = m.AlertStateUnknown
alert.NewStateDate = timeNow() alert.NewStateDate = timeNow()
_, err := sess.Insert(alert) _, err := sess.Insert(alert)
...@@ -300,7 +300,7 @@ func PauseAlert(cmd *m.PauseAlertCommand) error { ...@@ -300,7 +300,7 @@ func PauseAlert(cmd *m.PauseAlertCommand) error {
params = append(params, string(m.AlertStatePaused)) params = append(params, string(m.AlertStatePaused))
params = append(params, timeNow()) params = append(params, timeNow())
} else { } else {
params = append(params, string(m.AlertStatePending)) params = append(params, string(m.AlertStateUnknown))
params = append(params, timeNow()) params = append(params, timeNow())
} }
...@@ -324,7 +324,7 @@ func PauseAllAlerts(cmd *m.PauseAllAlertCommand) error { ...@@ -324,7 +324,7 @@ func PauseAllAlerts(cmd *m.PauseAllAlertCommand) error {
if cmd.Paused { if cmd.Paused {
newState = string(m.AlertStatePaused) newState = string(m.AlertStatePaused)
} else { } else {
newState = string(m.AlertStatePending) newState = string(m.AlertStateUnknown)
} }
res, err := sess.Exec(`UPDATE alert SET state = ?, new_state_date = ?`, newState, timeNow()) res, err := sess.Exec(`UPDATE alert SET state = ?, new_state_date = ?`, newState, timeNow())
......
...@@ -109,7 +109,7 @@ func TestAlertingDataAccess(t *testing.T) { ...@@ -109,7 +109,7 @@ func TestAlertingDataAccess(t *testing.T) {
So(alert.DashboardId, ShouldEqual, testDash.Id) So(alert.DashboardId, ShouldEqual, testDash.Id)
So(alert.PanelId, ShouldEqual, 1) So(alert.PanelId, ShouldEqual, 1)
So(alert.Name, ShouldEqual, "Alerting title") So(alert.Name, ShouldEqual, "Alerting title")
So(alert.State, ShouldEqual, "pending") So(alert.State, ShouldEqual, m.AlertStateUnknown)
So(alert.NewStateDate, ShouldNotBeNil) So(alert.NewStateDate, ShouldNotBeNil)
So(alert.EvalData, ShouldNotBeNil) So(alert.EvalData, ShouldNotBeNil)
So(alert.EvalData.Get("test").MustString(), ShouldEqual, "test") So(alert.EvalData.Get("test").MustString(), ShouldEqual, "test")
...@@ -154,7 +154,7 @@ func TestAlertingDataAccess(t *testing.T) { ...@@ -154,7 +154,7 @@ func TestAlertingDataAccess(t *testing.T) {
So(query.Result[0].Name, ShouldEqual, "Name") So(query.Result[0].Name, ShouldEqual, "Name")
Convey("Alert state should not be updated", func() { Convey("Alert state should not be updated", func() {
So(query.Result[0].State, ShouldEqual, "pending") So(query.Result[0].State, ShouldEqual, m.AlertStateUnknown)
}) })
}) })
......
...@@ -99,6 +99,13 @@ function getStateDisplayModel(state) { ...@@ -99,6 +99,13 @@ function getStateDisplayModel(state) {
stateClass: 'alert-state-warning', stateClass: 'alert-state-warning',
}; };
} }
case 'unknown': {
return {
text: 'UNKNOWN',
iconClass: 'fa fa-question',
stateClass: 'alert-state-paused',
};
}
} }
throw { message: 'Unknown alert state' }; throw { message: 'Unknown alert state' };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment