mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(notifications): make it possible to send test alert notifications
closes #5847
This commit is contained in:
parent
4c5461d4ba
commit
d11bc57c37
@ -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 {
|
||||
|
@ -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))
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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()
|
||||
|
93
pkg/services/alerting/test_notification.go
Normal file
93
pkg/services/alerting/test_notification.go
Normal file
@ -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
|
||||
}
|
@ -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);
|
||||
|
@ -60,7 +60,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-button-row">
|
||||
<button ng-click="ctrl.save()" class="btn btn-success">Save</button>
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form width-6">
|
||||
<button ng-click="ctrl.save()" class="btn btn-success">Save</button>
|
||||
</div>
|
||||
<div class="gf-form width-8">
|
||||
<button ng-click="ctrl.toggleTest()" class="btn btn-secondary">Test</button>
|
||||
</div>
|
||||
|
||||
<div class="gf-form width-20" ng-show="ctrl.showTest">
|
||||
<span class="gf-form-label width-13">Severity for test notification</span>
|
||||
<div class="gf-form-select-wrapper width-7">
|
||||
<select class="gf-form-input"
|
||||
ng-model="ctrl.testSeverity"
|
||||
ng-options="t for t in ['critical', 'warning', 'ok']">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form" ng-show="ctrl.showTest">
|
||||
<button ng-click="ctrl.testNotification()" class="btn btn-secondary">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user