Jelajahi Sumber

Merge pull request #13680 from davewat/add-notification-channel-option-to-disable-resolved-alert

Add channel option to disable the resolved alert (OK Message)
Carl Bergquist 7 tahun lalu
induk
melakukan
94e2d2b483

+ 26 - 23
pkg/api/dtos/alerting.go

@@ -49,28 +49,30 @@ func formatShort(interval time.Duration) string {
 
 func NewAlertNotification(notification *models.AlertNotification) *AlertNotification {
 	return &AlertNotification{
-		Id:           notification.Id,
-		Name:         notification.Name,
-		Type:         notification.Type,
-		IsDefault:    notification.IsDefault,
-		Created:      notification.Created,
-		Updated:      notification.Updated,
-		Frequency:    formatShort(notification.Frequency),
-		SendReminder: notification.SendReminder,
-		Settings:     notification.Settings,
+		Id:                    notification.Id,
+		Name:                  notification.Name,
+		Type:                  notification.Type,
+		IsDefault:             notification.IsDefault,
+		Created:               notification.Created,
+		Updated:               notification.Updated,
+		Frequency:             formatShort(notification.Frequency),
+		SendReminder:          notification.SendReminder,
+		DisableResolveMessage: notification.DisableResolveMessage,
+		Settings:              notification.Settings,
 	}
 }
 
 type AlertNotification struct {
-	Id           int64            `json:"id"`
-	Name         string           `json:"name"`
-	Type         string           `json:"type"`
-	IsDefault    bool             `json:"isDefault"`
-	SendReminder bool             `json:"sendReminder"`
-	Frequency    string           `json:"frequency"`
-	Created      time.Time        `json:"created"`
-	Updated      time.Time        `json:"updated"`
-	Settings     *simplejson.Json `json:"settings"`
+	Id                    int64            `json:"id"`
+	Name                  string           `json:"name"`
+	Type                  string           `json:"type"`
+	IsDefault             bool             `json:"isDefault"`
+	SendReminder          bool             `json:"sendReminder"`
+	DisableResolveMessage bool             `json:"disableResolveMessage"`
+	Frequency             string           `json:"frequency"`
+	Created               time.Time        `json:"created"`
+	Updated               time.Time        `json:"updated"`
+	Settings              *simplejson.Json `json:"settings"`
 }
 
 type AlertTestCommand struct {
@@ -100,11 +102,12 @@ type EvalMatch struct {
 }
 
 type NotificationTestCommand struct {
-	Name         string           `json:"name"`
-	Type         string           `json:"type"`
-	SendReminder bool             `json:"sendReminder"`
-	Frequency    string           `json:"frequency"`
-	Settings     *simplejson.Json `json:"settings"`
+	Name                  string           `json:"name"`
+	Type                  string           `json:"type"`
+	SendReminder          bool             `json:"sendReminder"`
+	DisableResolveMessage bool             `json:"disableResolveMessage"`
+	Frequency             string           `json:"frequency"`
+	Settings              *simplejson.Json `json:"settings"`
 }
 
 type PauseAlertCommand struct {

+ 26 - 23
pkg/models/alert_notifications.go

@@ -23,38 +23,41 @@ var (
 )
 
 type AlertNotification struct {
-	Id           int64            `json:"id"`
-	OrgId        int64            `json:"-"`
-	Name         string           `json:"name"`
-	Type         string           `json:"type"`
-	SendReminder bool             `json:"sendReminder"`
-	Frequency    time.Duration    `json:"frequency"`
-	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"`
+	SendReminder          bool             `json:"sendReminder"`
+	DisableResolveMessage bool             `json:"disableResolveMessage"`
+	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"`
-	SendReminder bool             `json:"sendReminder"`
-	Frequency    string           `json:"frequency"`
-	IsDefault    bool             `json:"isDefault"`
-	Settings     *simplejson.Json `json:"settings"`
+	Name                  string           `json:"name"  binding:"Required"`
+	Type                  string           `json:"type"  binding:"Required"`
+	SendReminder          bool             `json:"sendReminder"`
+	DisableResolveMessage bool             `json:"disableResolveMessage"`
+	Frequency             string           `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"`
-	SendReminder bool             `json:"sendReminder"`
-	Frequency    string           `json:"frequency"`
-	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"`
+	SendReminder          bool             `json:"sendReminder"`
+	DisableResolveMessage bool             `json:"disableResolveMessage"`
+	Frequency             string           `json:"frequency"`
+	IsDefault             bool             `json:"isDefault"`
+	Settings              *simplejson.Json `json:"settings"  binding:"Required"`
 
 	OrgId  int64 `json:"-"`
 	Result *AlertNotification

+ 1 - 0
pkg/services/alerting/interfaces.go

@@ -27,6 +27,7 @@ type Notifier interface {
 	GetNotifierId() int64
 	GetIsDefault() bool
 	GetSendReminder() bool
+	GetDisableResolveMessage() bool
 	GetFrequency() time.Duration
 }
 

+ 26 - 16
pkg/services/alerting/notifiers/base.go

@@ -6,7 +6,6 @@ import (
 
 	"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/models"
-
 	"github.com/grafana/grafana/pkg/services/alerting"
 )
 
@@ -15,13 +14,14 @@ const (
 )
 
 type NotifierBase struct {
-	Name         string
-	Type         string
-	Id           int64
-	IsDeault     bool
-	UploadImage  bool
-	SendReminder bool
-	Frequency    time.Duration
+	Name                  string
+	Type                  string
+	Id                    int64
+	IsDeault              bool
+	UploadImage           bool
+	SendReminder          bool
+	DisableResolveMessage bool
+	Frequency             time.Duration
 
 	log log.Logger
 }
@@ -34,14 +34,15 @@ func NewNotifierBase(model *models.AlertNotification) NotifierBase {
 	}
 
 	return NotifierBase{
-		Id:           model.Id,
-		Name:         model.Name,
-		IsDeault:     model.IsDefault,
-		Type:         model.Type,
-		UploadImage:  uploadImage,
-		SendReminder: model.SendReminder,
-		Frequency:    model.Frequency,
-		log:          log.New("alerting.notifier." + model.Name),
+		Id:                    model.Id,
+		Name:                  model.Name,
+		IsDeault:              model.IsDefault,
+		Type:                  model.Type,
+		UploadImage:           uploadImage,
+		SendReminder:          model.SendReminder,
+		DisableResolveMessage: model.DisableResolveMessage,
+		Frequency:             model.Frequency,
+		log:                   log.New("alerting.notifier." + model.Name),
 	}
 }
 
@@ -83,6 +84,11 @@ func (n *NotifierBase) ShouldNotify(ctx context.Context, context *alerting.EvalC
 		}
 	}
 
+	// Do not notify when state is OK if DisableResolveMessage is set to true
+	if context.Rule.State == models.AlertStateOK && n.DisableResolveMessage {
+		return false
+	}
+
 	return true
 }
 
@@ -106,6 +112,10 @@ func (n *NotifierBase) GetSendReminder() bool {
 	return n.SendReminder
 }
 
+func (n *NotifierBase) GetDisableResolveMessage() bool {
+	return n.DisableResolveMessage
+}
+
 func (n *NotifierBase) GetFrequency() time.Duration {
 	return n.Frequency
 }

+ 5 - 0
pkg/services/alerting/notifiers/base_test.go

@@ -179,5 +179,10 @@ func TestBaseNotifier(t *testing.T) {
 			base := NewNotifierBase(model)
 			So(base.UploadImage, ShouldBeTrue)
 		})
+
+		Convey("default value should be false for backwards compatibility", func() {
+			base := NewNotifierBase(model)
+			So(base.DisableResolveMessage, ShouldBeFalse)
+		})
 	})
 }

+ 14 - 10
pkg/services/sqlstore/alert_notification.go

@@ -66,6 +66,7 @@ func GetAlertNotificationsToSend(query *m.GetAlertNotificationsToSendQuery) erro
 										alert_notification.updated,
 										alert_notification.settings,
 										alert_notification.is_default,
+										alert_notification.disable_resolve_message,
 										alert_notification.send_reminder,
 										alert_notification.frequency
 										FROM alert_notification
@@ -106,6 +107,7 @@ func getAlertNotificationInternal(query *m.GetAlertNotificationsQuery, sess *DBS
 										alert_notification.updated,
 										alert_notification.settings,
 										alert_notification.is_default,
+										alert_notification.disable_resolve_message,
 										alert_notification.send_reminder,
 										alert_notification.frequency
 										FROM alert_notification
@@ -166,15 +168,16 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error
 		}
 
 		alertNotification := &m.AlertNotification{
-			OrgId:        cmd.OrgId,
-			Name:         cmd.Name,
-			Type:         cmd.Type,
-			Settings:     cmd.Settings,
-			SendReminder: cmd.SendReminder,
-			Frequency:    frequency,
-			Created:      time.Now(),
-			Updated:      time.Now(),
-			IsDefault:    cmd.IsDefault,
+			OrgId:                 cmd.OrgId,
+			Name:                  cmd.Name,
+			Type:                  cmd.Type,
+			Settings:              cmd.Settings,
+			SendReminder:          cmd.SendReminder,
+			DisableResolveMessage: cmd.DisableResolveMessage,
+			Frequency:             frequency,
+			Created:               time.Now(),
+			Updated:               time.Now(),
+			IsDefault:             cmd.IsDefault,
 		}
 
 		if _, err = sess.MustCols("send_reminder").Insert(alertNotification); err != nil {
@@ -210,6 +213,7 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
 		current.Type = cmd.Type
 		current.IsDefault = cmd.IsDefault
 		current.SendReminder = cmd.SendReminder
+		current.DisableResolveMessage = cmd.DisableResolveMessage
 
 		if current.SendReminder {
 			if cmd.Frequency == "" {
@@ -224,7 +228,7 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
 			current.Frequency = frequency
 		}
 
-		sess.UseBool("is_default", "send_reminder")
+		sess.UseBool("is_default", "send_reminder", "disable_resolve_message")
 
 		if affected, err := sess.ID(cmd.Id).Update(current); err != nil {
 			return err

+ 10 - 7
pkg/services/sqlstore/alert_notification_test.go

@@ -219,6 +219,7 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
 			So(cmd.Result.OrgId, ShouldNotEqual, 0)
 			So(cmd.Result.Type, ShouldEqual, "email")
 			So(cmd.Result.Frequency, ShouldEqual, 10*time.Second)
+			So(cmd.Result.DisableResolveMessage, ShouldBeFalse)
 
 			Convey("Cannot save Alert Notification with the same name", func() {
 				err = CreateAlertNotificationCommand(cmd)
@@ -227,18 +228,20 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
 
 			Convey("Can update alert notification", func() {
 				newCmd := &models.UpdateAlertNotificationCommand{
-					Name:         "NewName",
-					Type:         "webhook",
-					OrgId:        cmd.Result.OrgId,
-					SendReminder: true,
-					Frequency:    "60s",
-					Settings:     simplejson.New(),
-					Id:           cmd.Result.Id,
+					Name:                  "NewName",
+					Type:                  "webhook",
+					OrgId:                 cmd.Result.OrgId,
+					SendReminder:          true,
+					DisableResolveMessage: true,
+					Frequency:             "60s",
+					Settings:              simplejson.New(),
+					Id:                    cmd.Result.Id,
 				}
 				err := UpdateAlertNotification(newCmd)
 				So(err, ShouldBeNil)
 				So(newCmd.Result.Name, ShouldEqual, "NewName")
 				So(newCmd.Result.Frequency, ShouldEqual, 60*time.Second)
+				So(newCmd.Result.DisableResolveMessage, ShouldBeTrue)
 			})
 
 			Convey("Can update alert notification to disable sending of reminders", func() {

+ 3 - 0
pkg/services/sqlstore/migrations/alert_mig.go

@@ -71,6 +71,9 @@ func addAlertMigrations(mg *Migrator) {
 	mg.AddMigration("Add column send_reminder", NewAddColumnMigration(alert_notification, &Column{
 		Name: "send_reminder", Type: DB_Bool, Nullable: true, Default: "0",
 	}))
+	mg.AddMigration("Add column disable_resolve_message", NewAddColumnMigration(alert_notification, &Column{
+		Name: "disable_resolve_message", Type: DB_Bool, Nullable: false, Default: "0",
+	}))
 
 	mg.AddMigration("add index alert_notification org_id & name", NewAddIndexMigration(alert_notification, alert_notification.Indices[0]))
 

+ 1 - 0
public/app/features/alerting/NotificationsEditCtrl.ts

@@ -12,6 +12,7 @@ export class AlertNotificationEditCtrl {
   defaults: any = {
     type: 'email',
     sendReminder: false,
+    disableResolveMessage: false,
     frequency: '15m',
     settings: {
       httpMethod: 'POST',

+ 10 - 3
public/app/features/alerting/partials/notification_edit.html

@@ -21,21 +21,28 @@
       <gf-form-switch
           class="gf-form"
           label="Send on all alerts"
-          label-class="width-12"
+          label-class="width-14"
           checked="ctrl.model.isDefault"
           tooltip="Use this notification for all alerts">
       </gf-form-switch>
       <gf-form-switch
           class="gf-form"
           label="Include image"
-          label-class="width-12"
+          label-class="width-14"
           checked="ctrl.model.settings.uploadImage"
           tooltip="Captures an image and include it in the notification">
       </gf-form-switch>
+      <gf-form-switch
+          class="gf-form"
+          label="Disable Resolve Message"
+          label-class="width-14"
+          checked="ctrl.model.disableResolveMessage"
+          tooltip="Disable the resolve message [OK] that is sent when alerting state returns to false">
+      </gf-form-switch>
       <gf-form-switch
           class="gf-form"
           label="Send reminders"
-          label-class="width-12"
+          label-class="width-14"
           checked="ctrl.model.sendReminder"
           tooltip="Send additional notifications for triggered alerts">
       </gf-form-switch>