Browse Source

Add a new notifier : DingTalk (#8473)

* add alerting notifier: DingDing

* add alerting notifier: DingDing

* add dingding unit test

* add dingding unit test

* delete debug code & format code style.

* fix build failed: dingding_test.go
Liang Jiameng 8 years ago
parent
commit
109fd998ed

+ 2 - 0
pkg/metrics/metrics.go

@@ -44,6 +44,7 @@ var (
 	M_Alerting_Notification_Sent_Slack     Counter
 	M_Alerting_Notification_Sent_Email     Counter
 	M_Alerting_Notification_Sent_Webhook   Counter
+	M_Alerting_Notification_Sent_DingDing  Counter
 	M_Alerting_Notification_Sent_PagerDuty Counter
 	M_Alerting_Notification_Sent_LINE      Counter
 	M_Alerting_Notification_Sent_Victorops Counter
@@ -116,6 +117,7 @@ func initMetricVars(settings *MetricSettings) {
 	M_Alerting_Notification_Sent_Slack = RegCounter("alerting.notifications_sent", "type", "slack")
 	M_Alerting_Notification_Sent_Email = RegCounter("alerting.notifications_sent", "type", "email")
 	M_Alerting_Notification_Sent_Webhook = RegCounter("alerting.notifications_sent", "type", "webhook")
+	M_Alerting_Notification_Sent_DingDing = RegCounter("alerting.notifications_sent", "type", "dingding")
 	M_Alerting_Notification_Sent_PagerDuty = RegCounter("alerting.notifications_sent", "type", "pagerduty")
 	M_Alerting_Notification_Sent_Victorops = RegCounter("alerting.notifications_sent", "type", "victorops")
 	M_Alerting_Notification_Sent_OpsGenie = RegCounter("alerting.notifications_sent", "type", "opsgenie")

+ 90 - 0
pkg/services/alerting/notifiers/dingding.go

@@ -0,0 +1,90 @@
+package notifiers
+
+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/metrics"
+	m "github.com/grafana/grafana/pkg/models"
+	"github.com/grafana/grafana/pkg/services/alerting"
+)
+
+func init() {
+	alerting.RegisterNotifier(&alerting.NotifierPlugin{
+		Type:        "dingding",
+		Name:        "DingDing",
+		Description: "Sends HTTP POST request to DingDing",
+		Factory:     NewDingDingNotifier,
+		OptionsTemplate: `
+      <h3 class="page-heading">DingDing settings</h3>
+      <div class="gf-form">
+        <span class="gf-form-label width-10">Url</span>
+        <input type="text" required class="gf-form-input max-width-26" ng-model="ctrl.model.settings.url"></input>
+      </div>
+    `,
+	})
+
+}
+
+func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
+	url := model.Settings.Get("url").MustString()
+	if url == "" {
+		return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
+	}
+
+	return &DingDingNotifier{
+		NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
+		Url:          url,
+		log:          log.New("alerting.notifier.dingding"),
+	}, nil
+}
+
+type DingDingNotifier struct {
+	NotifierBase
+	Url string
+	log log.Logger
+}
+
+func (this *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error {
+	this.log.Info("Sending dingding")
+	metrics.M_Alerting_Notification_Sent_DingDing.Inc(1)
+
+	messageUrl, err := evalContext.GetRuleUrl()
+	if err != nil {
+		this.log.Error("Failed to get messageUrl", "error", err, "dingding", this.Name)
+		messageUrl = ""
+	}
+	this.log.Info("messageUrl:" + messageUrl)
+
+	message := evalContext.Rule.Message
+	picUrl := evalContext.ImagePublicUrl
+	title := evalContext.GetNotificationTitle()
+
+	bodyJSON, err := simplejson.NewJson([]byte(`{
+		"msgtype": "link",
+		"link": {
+			"text": "` + message + `",
+			"title": "` + title + `",
+			"picUrl": "` + picUrl + `",
+			"messageUrl": "` + messageUrl + `"
+		}
+	}`))
+
+	if err != nil {
+		this.log.Error("Failed to create Json data", "error", err, "dingding", this.Name)
+	}
+
+	body, _ := bodyJSON.MarshalJSON()
+
+	cmd := &m.SendWebhookSync{
+		Url:  this.Url,
+		Body: string(body),
+	}
+
+	if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
+		this.log.Error("Failed to send DingDing", "error", err, "dingding", this.Name)
+		return err
+	}
+
+	return nil
+}

+ 49 - 0
pkg/services/alerting/notifiers/dingding_test.go

@@ -0,0 +1,49 @@
+package notifiers
+
+import (
+	"testing"
+
+	"github.com/grafana/grafana/pkg/components/simplejson"
+	m "github.com/grafana/grafana/pkg/models"
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func TestDingDingNotifier(t *testing.T) {
+	Convey("Line notifier tests", t, func() {
+		Convey("empty settings should return error", func() {
+			json := `{ }`
+
+			settingsJSON, _ := simplejson.NewJson([]byte(json))
+			model := &m.AlertNotification{
+				Name:     "dingding_testing",
+				Type:     "dingding",
+				Settings: settingsJSON,
+			}
+
+			_, err := NewDingDingNotifier(model)
+			So(err, ShouldNotBeNil)
+
+		})
+		Convey("settings should trigger incident", func() {
+			json := `
+			{
+  "url": "https://www.google.com"
+			}`
+			settingsJSON, _ := simplejson.NewJson([]byte(json))
+			model := &m.AlertNotification{
+				Name:     "dingding_testing",
+				Type:     "dingding",
+				Settings: settingsJSON,
+			}
+
+			not, err := NewDingDingNotifier(model)
+			notifier := not.(*DingDingNotifier)
+
+			So(err, ShouldBeNil)
+			So(notifier.Name, ShouldEqual, "dingding_testing")
+			So(notifier.Type, ShouldEqual, "dingding")
+			So(notifier.Url, ShouldEqual, "https://www.google.com")
+		})
+
+	})
+}