From 212fd272526e0e2f99fd68e7f673117d03deac0e Mon Sep 17 00:00:00 2001 From: bergquist Date: Fri, 17 Jun 2016 15:30:17 +0200 Subject: [PATCH] feat(alerting): add support for email notifications --- emails/templates/alert_notification.html | 29 +++ pkg/services/alerting/notifier.go | 31 ++- .../notifications/notifications_test.go | 85 ++++++++- public/emails/alert_notification.html | 177 ++++++++++++++++++ 4 files changed, 311 insertions(+), 11 deletions(-) create mode 100644 emails/templates/alert_notification.html create mode 100644 public/emails/alert_notification.html diff --git a/emails/templates/alert_notification.html b/emails/templates/alert_notification.html new file mode 100644 index 00000000000..763d05b6733 --- /dev/null +++ b/emails/templates/alert_notification.html @@ -0,0 +1,29 @@ + + +[[Subject .Subject "Grafana Alert: [ [[.State]] ] [[.Name]]" ]] + +Alertstate: [[.State]]
+[[.AlertPageUrl]]"
+[[.DashboardLink]]"
+[[.Description]]
+ +[[if eq .State "Ok"]] + Everything is Ok +[[end]] + +[[if ne .State "Ok" ]] + + + + + + + [[ range $ta := .TriggeredAlerts]] + + + + + + [[end]] +
SerieStateActual value
[[$ta.Name]][[$ta.State]][[$ta.ActualValue]]
+[[end]] diff --git a/pkg/services/alerting/notifier.go b/pkg/services/alerting/notifier.go index 13588373bf3..a7214311d97 100644 --- a/pkg/services/alerting/notifier.go +++ b/pkg/services/alerting/notifier.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/log" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/alerting/alertstates" + "github.com/grafana/grafana/pkg/setting" ) type NotifierImpl struct { @@ -50,18 +51,28 @@ type EmailNotifier struct { func (this *EmailNotifier) Dispatch(alertResult *AlertResult) { this.log.Info("Sending email") - cmd := &m.SendEmailCommand{ - Data: map[string]interface{}{ - "Description": alertResult.Description, - "TriggeredAlerts": alertResult.TriggeredAlerts, - }, - To: []string{this.To}, - Info: "Alert result", - Massive: false, - Template: "", + grafanaUrl := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort) + if setting.AppSubUrl != "" { + grafanaUrl += "/" + setting.AppSubUrl } - bus.Dispatch(cmd) + cmd := &m.SendEmailCommand{ + Data: map[string]interface{}{ + "Name": "Name", + "State": alertResult.State, + "Description": alertResult.Description, + "TriggeredAlerts": alertResult.TriggeredAlerts, + "DashboardLink": grafanaUrl + "/dashboard/db/alerting", + "AlertPageUrl": grafanaUrl + "/alerting", + }, + To: []string{this.To}, + Template: "alert_notification.html", + } + + err := bus.Dispatch(cmd) + if err != nil { + this.log.Error("Could not send alert notification as email", "error", err) + } } type WebhookNotifier struct { diff --git a/pkg/services/notifications/notifications_test.go b/pkg/services/notifications/notifications_test.go index 110e24cb810..bbc7a6df587 100644 --- a/pkg/services/notifications/notifications_test.go +++ b/pkg/services/notifications/notifications_test.go @@ -9,6 +9,12 @@ import ( . "github.com/smartystreets/goconvey/convey" ) +type testTriggeredAlert struct { + ActualValue float64 + Name string + State string +} + func TestNotifications(t *testing.T) { Convey("Given the notifications service", t, func() { @@ -34,6 +40,83 @@ func TestNotifications(t *testing.T) { So(sentMsg.Subject, ShouldEqual, "Reset your Grafana password - asd@asd.com") So(sentMsg.Body, ShouldNotContainSubstring, "Subject") }) - }) + Convey("Alert notifications", func() { + Convey("When sending reset email password", func() { + cmd := &m.SendEmailCommand{ + Data: map[string]interface{}{ + "Name": "Name", + "State": "Critical", + "Description": "Description", + "DashboardLink": "http://localhost:3000/dashboard/db/alerting", + "AlertPageUrl": "http://localhost:3000/alerting", + "TriggeredAlerts": []testTriggeredAlert{ + {Name: "desktop", State: "Critical", ActualValue: 13}, + {Name: "mobile", State: "Warn", ActualValue: 5}, + }, + }, + To: []string{"asd@asd.com "}, + Template: "alert_notification.html", + } + + err := sendEmailCommandHandler(cmd) + So(err, ShouldBeNil) + + So(sentMsg.Body, ShouldContainSubstring, "Alertstate: Critical") + So(sentMsg.Body, ShouldContainSubstring, "http://localhost:3000/dashboard/db/alerting") + So(sentMsg.Body, ShouldContainSubstring, "Critical") + So(sentMsg.Body, ShouldContainSubstring, "Warn") + So(sentMsg.Body, ShouldContainSubstring, "mobile") + So(sentMsg.Body, ShouldContainSubstring, "desktop") + + So(sentMsg.Subject, ShouldContainSubstring, "Grafana Alert: [ Critical ] ") + }) + + Convey("given critical", func() { + cmd := &m.SendEmailCommand{ + Data: map[string]interface{}{ + "Name": "Name", + "State": "Warn", + "Description": "Description", + "DashboardLink": "http://localhost:3000/dashboard/db/alerting", + "AlertPageUrl": "http://localhost:3000/alerting", + "TriggeredAlerts": []testTriggeredAlert{ + {Name: "desktop", State: "Critical", ActualValue: 13}, + {Name: "mobile", State: "Warn", ActualValue: 5}, + }, + }, + To: []string{"asd@asd.com "}, + Template: "alert_notification.html", + } + + err := sendEmailCommandHandler(cmd) + So(err, ShouldBeNil) + So(sentMsg.Body, ShouldContainSubstring, "Alertstate: Warn") + So(sentMsg.Body, ShouldContainSubstring, "http://localhost:3000/dashboard/db/alerting") + So(sentMsg.Body, ShouldContainSubstring, "Critical") + So(sentMsg.Body, ShouldContainSubstring, "Warn") + So(sentMsg.Body, ShouldContainSubstring, "mobile") + So(sentMsg.Body, ShouldContainSubstring, "desktop") + So(sentMsg.Subject, ShouldContainSubstring, "Grafana Alert: [ Warn ]") + }) + + Convey("given ok", func() { + cmd := &m.SendEmailCommand{ + Data: map[string]interface{}{ + "Name": "Name", + "State": "Ok", + "Description": "Description", + "DashboardLink": "http://localhost:3000/dashboard/db/alerting", + "AlertPageUrl": "http://localhost:3000/alerting", + }, + To: []string{"asd@asd.com "}, + Template: "alert_notification.html", + } + + err := sendEmailCommandHandler(cmd) + So(err, ShouldBeNil) + So(sentMsg.Subject, ShouldContainSubstring, "Grafana Alert: [ Ok ]") + }) + }) + }) } diff --git a/public/emails/alert_notification.html b/public/emails/alert_notification.html new file mode 100644 index 00000000000..1b905b8c378 --- /dev/null +++ b/public/emails/alert_notification.html @@ -0,0 +1,177 @@ + + + + + + + + + + + + + +
+
+ + + + + +
+
+ + + + + +
+ + + + + + +
+ +
+ +
+ +
+
+ + + + + + +
+ + +{{Subject .Subject "Grafana Alert: [ {{.State}} ] {{.Name}}" }} + +Alertstate: {{.State}}
+{{.AlertPageUrl}}"
+{{.DashboardLink}}"
+{{.Description}}
+ +{{if eq .State "Ok"}} + Everything is Ok +{{end}} + +{{if ne .State "Ok" }} + + + + + + + {{ range $ta := .TriggeredAlerts}} + + + + + + {{end}} +
+{{end}} + + + + + + + + + +
+
+
+ +