diff --git a/pkg/api/alerting.go b/pkg/api/alerting.go index 80b5108bbad..10492cb9a47 100644 --- a/pkg/api/alerting.go +++ b/pkg/api/alerting.go @@ -214,6 +214,22 @@ func DeleteAlertNotification(c *middleware.Context) Response { return ApiSuccess("Notification deleted") } +//POST /api/alert-notifications/test +func NotificationTest(c *middleware.Context, dto dtos.NotificationTestCommand) Response { + cmd := &alerting.NotificationTestCommand{ + Name: dto.Name, + Type: dto.Type, + Severity: dto.Severity, + Settings: dto.Settings, + } + + if err := bus.Dispatch(cmd); err != nil { + return ApiError(500, "Failed to send alert notifications", err) + } + + return ApiSuccess("Test notification sent") +} + func GetAlertHistory(c *middleware.Context) Response { alertId, err := getAlertIdForRequest(c) if err != nil { diff --git a/pkg/api/api.go b/pkg/api/api.go index 132c609dde4..de3a1de8a65 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -259,6 +259,7 @@ func Register(r *macaron.Macaron) { r.Get("/alert-notifications", wrap(GetAlertNotifications)) r.Group("/alert-notifications", func() { + r.Post("/test", bind(dtos.NotificationTestCommand{}), wrap(NotificationTest)) r.Post("/", bind(m.CreateAlertNotificationCommand{}), wrap(CreateAlertNotification)) r.Put("/:notificationId", bind(m.UpdateAlertNotificationCommand{}), wrap(UpdateAlertNotification)) r.Get("/:notificationId", wrap(GetAlertNotificationById)) diff --git a/pkg/api/dtos/alerting.go b/pkg/api/dtos/alerting.go index d5fbb2c3a9f..474f0a5a048 100644 --- a/pkg/api/dtos/alerting.go +++ b/pkg/api/dtos/alerting.go @@ -63,3 +63,10 @@ type AlertHistory struct { Data *simplejson.Json `json:"data"` } + +type NotificationTestCommand struct { + Name string `json:"name"` + Type string `json:"type"` + Settings *simplejson.Json `json:"settings"` + Severity string `json:"severity"` +} diff --git a/pkg/services/alerting/notifier.go b/pkg/services/alerting/notifier.go index c345594de2c..55090d9772f 100644 --- a/pkg/services/alerting/notifier.go +++ b/pkg/services/alerting/notifier.go @@ -46,6 +46,10 @@ func (n *RootNotifier) Notify(context *EvalContext) { n.log.Error("Failed to upload alert panel image", "error", err) } + n.sendNotifications(notifiers, context) +} + +func (n *RootNotifier) sendNotifications(notifiers []Notifier, context *EvalContext) { for _, notifier := range notifiers { n.log.Info("Sending notification", "firing", context.Firing, "type", notifier.GetType()) go notifier.Notify(context) @@ -53,7 +57,6 @@ func (n *RootNotifier) Notify(context *EvalContext) { } func (n *RootNotifier) uploadImage(context *EvalContext) error { - uploader, _ := imguploader.NewImageUploader() imageUrl, err := context.GetImageUrl() diff --git a/pkg/services/alerting/test_notification.go b/pkg/services/alerting/test_notification.go new file mode 100644 index 00000000000..026dfdd18a5 --- /dev/null +++ b/pkg/services/alerting/test_notification.go @@ -0,0 +1,93 @@ +package alerting + +import ( + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/log" + "github.com/grafana/grafana/pkg/models" +) + +type NotificationTestCommand struct { + Severity string + Name string + Type string + Settings *simplejson.Json +} + +func init() { + bus.AddHandler("alerting", handleNotificationTestCommand) + +} + +func handleNotificationTestCommand(cmd *NotificationTestCommand) error { + notifier := NewRootNotifier() + + model := &models.AlertNotification{ + Name: cmd.Name, + Type: cmd.Type, + Settings: cmd.Settings, + } + + notifiers, err := notifier.getNotifierFor(model) + + if err != nil { + log.Error2("Failed to create notifier", "error", err.Error()) + return err + } + + severity := models.AlertSeverityType(cmd.Severity) + notifier.sendNotifications([]Notifier{notifiers}, createTestEvalContext(severity)) + + return nil +} + +func createTestEvalContext(severity models.AlertSeverityType) *EvalContext { + state := models.AlertStateOK + firing := false + if severity == models.AlertSeverityCritical { + state = models.AlertStateCritical + firing = true + } + if severity == models.AlertSeverityWarning { + state = models.AlertStateWarning + firing = true + } + + testRule := &Rule{ + DashboardId: 1, + PanelId: 1, + Name: "Test notification", + Message: "Someone is testing the alert notification within grafana.", + State: state, + Severity: severity, + } + + ctx := NewEvalContext(testRule) + ctx.ImagePublicUrl = "http://grafana.org/assets/img/blog/mixed_styles.png" + + ctx.IsTestRun = true + ctx.Firing = firing + ctx.Error = nil + ctx.EvalMatches = evalMatchesBasedOnSeverity(severity) + + return ctx +} + +func evalMatchesBasedOnSeverity(severity models.AlertSeverityType) []*EvalMatch { + matches := make([]*EvalMatch, 0) + if severity == models.AlertSeverityOK { + return matches + } + + matches = append(matches, &EvalMatch{ + Metric: "High value", + Value: 100, + }) + + matches = append(matches, &EvalMatch{ + Metric: "Higher Value", + Value: 200, + }) + + return matches +} diff --git a/public/app/features/alerting/notification_edit_ctrl.ts b/public/app/features/alerting/notification_edit_ctrl.ts index fc33118cb00..99193a9d7d1 100644 --- a/public/app/features/alerting/notification_edit_ctrl.ts +++ b/public/app/features/alerting/notification_edit_ctrl.ts @@ -7,6 +7,8 @@ import config from 'app/core/config'; export class AlertNotificationEditCtrl { model: any; + showTest: boolean = false; + testSeverity: string = "critical"; /** @ngInject */ constructor(private $routeParams, private backendSrv, private $scope, private $location) { @@ -47,6 +49,24 @@ export class AlertNotificationEditCtrl { typeChanged() { this.model.settings = {}; } + + toggleTest() { + this.showTest = !this.showTest; + } + + testNotification() { + var payload = { + name: this.model.name, + type: this.model.type, + settings: this.model.settings, + severity: this.testSeverity + }; + + this.backendSrv.post(`/api/alert-notifications/test`, payload) + .then(res => { + this.$scope.appEvent('alert-succes', ['Test notification sent', '']); + }); + } } coreModule.controller('AlertNotificationEditCtrl', AlertNotificationEditCtrl); diff --git a/public/app/features/alerting/partials/notification_edit.html b/public/app/features/alerting/partials/notification_edit.html index 2faf3e2dfe0..5664d201967 100644 --- a/public/app/features/alerting/partials/notification_edit.html +++ b/public/app/features/alerting/partials/notification_edit.html @@ -60,7 +60,27 @@ -
- +
+
+
+ +
+
+ +
+ +
+ Severity for test notification +
+ +
+
+
+ +
+