mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(alerting): removes pause per datasource
This commit is contained in:
parent
6b9db0c0c5
commit
ecdf1888c4
@ -287,20 +287,11 @@ func PauseAlert(c *middleware.Context, dto dtos.PauseAlertCommand) Response {
|
||||
}
|
||||
|
||||
//POST /api/alerts/pause
|
||||
func PauseAlerts(c *middleware.Context, dto dtos.PauseAlertsCommand) Response {
|
||||
updateCmd := models.PauseAlertCommand{
|
||||
OrgId: c.OrgId,
|
||||
func PauseAlerts(c *middleware.Context, dto dtos.PauseAllAlertsCommand) Response {
|
||||
updateCmd := models.PauseAllAlertCommand{
|
||||
Paused: dto.Paused,
|
||||
}
|
||||
|
||||
if len(dto.DataSourceIds) > 0 {
|
||||
alertIdsToUpdate, err := getAlertIdsToUpdate(dto)
|
||||
if err != nil {
|
||||
return ApiError(500, "Failed to pause alerts", err)
|
||||
}
|
||||
updateCmd.AlertIds = alertIdsToUpdate
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&updateCmd); err != nil {
|
||||
return ApiError(500, "Failed to pause alerts", err)
|
||||
}
|
||||
@ -320,36 +311,3 @@ func PauseAlerts(c *middleware.Context, dto dtos.PauseAlertsCommand) Response {
|
||||
|
||||
return Json(200, result)
|
||||
}
|
||||
|
||||
func getAlertIdsToUpdate(pauseAlertCmd dtos.PauseAlertsCommand) ([]int64, error) {
|
||||
cmd := &models.GetAllAlertsQuery{}
|
||||
if err := bus.Dispatch(cmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var alertIdsToUpdate []int64
|
||||
for _, alert := range cmd.Result {
|
||||
alert, err := alerting.NewRuleFromDBAlert(alert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, condition := range alert.Conditions {
|
||||
id, exist := condition.GetDatasourceId()
|
||||
if exist && existInSlice(pauseAlertCmd.DataSourceIds, *id) {
|
||||
alertIdsToUpdate = append(alertIdsToUpdate, alert.Id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alertIdsToUpdate, nil
|
||||
}
|
||||
|
||||
func existInSlice(slice []int64, value int64) bool {
|
||||
for _, v := range slice {
|
||||
if v == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -256,7 +256,6 @@ func Register(r *macaron.Macaron) {
|
||||
r.Group("/alerts", func() {
|
||||
r.Post("/test", bind(dtos.AlertTestCommand{}), wrap(AlertTest))
|
||||
r.Post("/:alertId/pause", bind(dtos.PauseAlertCommand{}), wrap(PauseAlert), reqEditorRole)
|
||||
r.Post("/pause", bind(dtos.PauseAlertsCommand{}), wrap(PauseAlerts), reqGrafanaAdmin)
|
||||
r.Get("/:alertId", ValidateOrgAlert, wrap(GetAlert))
|
||||
r.Get("/", wrap(GetAlerts))
|
||||
r.Get("/states-for-dashboard", wrap(GetAlertStatesForDashboard))
|
||||
@ -290,6 +289,7 @@ func Register(r *macaron.Macaron) {
|
||||
r.Get("/users/:id/quotas", wrap(GetUserQuotas))
|
||||
r.Put("/users/:id/quotas/:target", bind(m.UpdateUserQuotaCmd{}), wrap(UpdateUserQuota))
|
||||
r.Get("/stats", AdminGetStats)
|
||||
r.Post("/pause-all-alerts", bind(dtos.PauseAllAlertsCommand{}), wrap(PauseAlerts))
|
||||
}, reqGrafanaAdmin)
|
||||
|
||||
// rendering
|
||||
|
@ -65,7 +65,6 @@ type PauseAlertCommand struct {
|
||||
Paused bool `json:"paused"`
|
||||
}
|
||||
|
||||
type PauseAlertsCommand struct {
|
||||
DataSourceIds []int64 `json:"datasourceId"`
|
||||
Paused bool `json:"paused"`
|
||||
type PauseAllAlertsCommand struct {
|
||||
Paused bool `json:"paused"`
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ var (
|
||||
|
||||
// Timers
|
||||
M_DataSource_ProxyReq_Timer Timer
|
||||
M_Alerting_Execution_Time Timer
|
||||
M_Alerting_Execution_Time Timer
|
||||
|
||||
// StatTotals
|
||||
M_Alerting_Active_Alerts Gauge
|
||||
|
@ -3,6 +3,8 @@ package models
|
||||
import (
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
)
|
||||
|
||||
@ -31,6 +33,10 @@ const (
|
||||
ExecutionErrorKeepState ExecutionErrorOption = "keep_state"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCannotChangeStateOnPausedAlert error = fmt.Errorf("Cannot change state on pause alert")
|
||||
)
|
||||
|
||||
func (s AlertStateType) IsValid() bool {
|
||||
return s == AlertStateOK || s == AlertStateNoData || s == AlertStatePaused || s == AlertStatePending
|
||||
}
|
||||
@ -138,6 +144,11 @@ type PauseAlertCommand struct {
|
||||
Paused bool
|
||||
}
|
||||
|
||||
type PauseAllAlertCommand struct {
|
||||
ResultCount int64
|
||||
Paused bool
|
||||
}
|
||||
|
||||
type SetAlertStateCommand struct {
|
||||
AlertId int64
|
||||
OrgId int64
|
||||
|
@ -34,10 +34,6 @@ type AlertQuery struct {
|
||||
To string
|
||||
}
|
||||
|
||||
func (c *QueryCondition) GetDatasourceId() (datasourceId *int64, exist bool) {
|
||||
return &c.Query.DatasourceId, true
|
||||
}
|
||||
|
||||
func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.ConditionResult, error) {
|
||||
timeRange := tsdb.NewTimeRange(c.Query.From, c.Query.To)
|
||||
|
||||
|
@ -30,5 +30,4 @@ type ConditionResult struct {
|
||||
|
||||
type Condition interface {
|
||||
Eval(result *EvalContext) (*ConditionResult, error)
|
||||
GetDatasourceId() (datasourceId *int64, exist bool)
|
||||
}
|
||||
|
@ -86,6 +86,10 @@ func (handler *DefaultResultHandler) Handle(evalContext *EvalContext) error {
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(cmd); err != nil {
|
||||
if err == m.ErrCannotChangeStateOnPausedAlert {
|
||||
handler.log.Error("Cannot change state on alert thats pause", "error", err)
|
||||
return err
|
||||
}
|
||||
handler.log.Error("Failed to save state", "error", err)
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,6 @@ func (f *FakeCondition) Eval(context *EvalContext) (*ConditionResult, error) {
|
||||
return &ConditionResult{}, nil
|
||||
}
|
||||
|
||||
func (c *FakeCondition) GetDatasourceId() (datasourceId *int64, exist bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func TestAlertRuleModel(t *testing.T) {
|
||||
Convey("Testing alert rule", t, func() {
|
||||
|
||||
|
@ -3,9 +3,8 @@ package sqlstore
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@ -21,6 +20,7 @@ func init() {
|
||||
bus.AddHandler("sql", SetAlertState)
|
||||
bus.AddHandler("sql", GetAlertStatesForDashboard)
|
||||
bus.AddHandler("sql", PauseAlertRule)
|
||||
bus.AddHandler("sql", PauseAllAlertRule)
|
||||
}
|
||||
|
||||
func GetAlertById(query *m.GetAlertByIdQuery) error {
|
||||
@ -230,6 +230,10 @@ func SetAlertState(cmd *m.SetAlertStateCommand) error {
|
||||
return fmt.Errorf("Could not find alert")
|
||||
}
|
||||
|
||||
if alert.State == m.AlertStatePaused {
|
||||
return m.ErrCannotChangeStateOnPausedAlert
|
||||
}
|
||||
|
||||
alert.State = cmd.State
|
||||
alert.StateChanges += 1
|
||||
alert.NewStateDate = time.Now()
|
||||
@ -248,6 +252,10 @@ func SetAlertState(cmd *m.SetAlertStateCommand) error {
|
||||
|
||||
func PauseAlertRule(cmd *m.PauseAlertCommand) error {
|
||||
return inTransaction(func(sess *xorm.Session) error {
|
||||
if len(cmd.AlertIds) == 0 {
|
||||
return fmt.Errorf("command contains no alertids")
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
params := make([]interface{}, 0)
|
||||
|
||||
@ -258,11 +266,9 @@ func PauseAlertRule(cmd *m.PauseAlertCommand) error {
|
||||
params = append(params, string(m.AlertStatePending))
|
||||
}
|
||||
|
||||
if len(cmd.AlertIds) > 0 {
|
||||
buffer.WriteString(` WHERE id IN (?` + strings.Repeat(",?", len(cmd.AlertIds)-1) + `)`)
|
||||
for _, v := range cmd.AlertIds {
|
||||
params = append(params, v)
|
||||
}
|
||||
buffer.WriteString(` WHERE id IN (?` + strings.Repeat(",?", len(cmd.AlertIds)-1) + `)`)
|
||||
for _, v := range cmd.AlertIds {
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
res, err := sess.Exec(buffer.String(), params...)
|
||||
@ -274,6 +280,24 @@ func PauseAlertRule(cmd *m.PauseAlertCommand) error {
|
||||
})
|
||||
}
|
||||
|
||||
func PauseAllAlertRule(cmd *m.PauseAllAlertCommand) error {
|
||||
return inTransaction(func(sess *xorm.Session) error {
|
||||
var newState string
|
||||
if cmd.Paused {
|
||||
newState = string(m.AlertStatePaused)
|
||||
} else {
|
||||
newState = string(m.AlertStatePending)
|
||||
}
|
||||
|
||||
res, err := sess.Exec(`UPDATE alert SET state = ?`, newState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.ResultCount, _ = res.RowsAffected()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func GetAlertStatesForDashboard(query *m.GetAlertStatesForDashboardQuery) error {
|
||||
var rawSql = `SELECT
|
||||
id,
|
||||
|
@ -39,6 +39,37 @@ func TestAlertingDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("Can set new states", func() {
|
||||
Convey("new state ok", func() {
|
||||
cmd := &m.SetAlertStateCommand{
|
||||
AlertId: 1,
|
||||
State: m.AlertStateOK,
|
||||
}
|
||||
|
||||
err = SetAlertState(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("can pause alert", func() {
|
||||
cmd := &m.PauseAllAlertCommand{
|
||||
Paused: true,
|
||||
}
|
||||
|
||||
err = PauseAllAlertRule(cmd)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("cannot updated paused alert", func() {
|
||||
cmd := &m.SetAlertStateCommand{
|
||||
AlertId: 1,
|
||||
State: m.AlertStateOK,
|
||||
}
|
||||
|
||||
err = SetAlertState(cmd)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Can read properties", func() {
|
||||
alertQuery := m.GetAlertsQuery{DashboardId: testDash.Id, PanelId: 1, OrgId: 1}
|
||||
err2 := HandleAlertsQuery(&alertQuery)
|
||||
|
Loading…
Reference in New Issue
Block a user