diff --git a/pkg/models/alerts.go b/pkg/models/alerts.go index f1dd17b23cc..caf4d4100b4 100644 --- a/pkg/models/alerts.go +++ b/pkg/models/alerts.go @@ -6,19 +6,20 @@ import ( ) type AlertRule struct { - Id int64 - OrgId int64 - DashboardId int64 - PanelId int64 - Query string - QueryRefId string - WarnLevel string - CritLevel string - Interval string - Title string - Description string - QueryRange string - Aggregator string + Id int64 + OrgId int64 + DashboardId int64 + PanelId int64 + Query string + QueryRefId string + WarnLevel string + CritLevel string + Interval string + Title string + Description string + QueryRange string + Aggregator string + DatasourceName string } type AlertRuleChange struct { @@ -39,18 +40,19 @@ func (cmd *SaveDashboardCommand) GetAlertModels() *[]AlertRule { alerting := panel.Get("alerting") alert := AlertRule{ - DashboardId: cmd.Result.Id, - OrgId: cmd.Result.OrgId, - PanelId: panel.Get("id").MustInt64(), - Id: alerting.Get("id").MustInt64(), - QueryRefId: alerting.Get("queryRef").MustString(), - WarnLevel: alerting.Get("warnLevel").MustString(), - CritLevel: alerting.Get("critLevel").MustString(), - Interval: alerting.Get("interval").MustString(), - Title: alerting.Get("title").MustString(), - Description: alerting.Get("description").MustString(), - QueryRange: alerting.Get("queryRange").MustString(), - Aggregator: alerting.Get("aggregator").MustString(), + DashboardId: cmd.Result.Id, + OrgId: cmd.Result.OrgId, + PanelId: panel.Get("id").MustInt64(), + DatasourceName: panel.Get("datasource").MustString(), + Id: alerting.Get("id").MustInt64(), + QueryRefId: alerting.Get("queryRef").MustString(), + WarnLevel: alerting.Get("warnLevel").MustString(), + CritLevel: alerting.Get("critLevel").MustString(), + Interval: alerting.Get("interval").MustString(), + Title: alerting.Get("title").MustString(), + Description: alerting.Get("description").MustString(), + QueryRange: alerting.Get("queryRange").MustString(), + Aggregator: alerting.Get("aggregator").MustString(), } for _, targetsObj := range panel.Get("targets").MustArray() { diff --git a/pkg/models/alerts_test.go b/pkg/models/alerts_test.go index d9a3da9ef3b..a2978c2ddc2 100644 --- a/pkg/models/alerts_test.go +++ b/pkg/models/alerts_test.go @@ -3,7 +3,6 @@ package models import ( "testing" - "fmt" "github.com/grafana/grafana/pkg/components/simplejson" . "github.com/smartystreets/goconvey/convey" ) @@ -12,7 +11,7 @@ func TestAlertModel(t *testing.T) { Convey("Parsing alerts from dashboard", t, func() { json := `{ - "id": 7, + "id": 57, "title": "Graphite 4", "originalTitle": "Graphite 4", "tags": [ @@ -30,92 +29,172 @@ func TestAlertModel(t *testing.T) { "height": "250px", "panels": [ { - "aliasColors": {}, - "bars": false, - "datasource": null, - "editable": true, + "title": "Active desktop users", "error": false, - "fill": 1, - "grid": { - "threshold1": null, - "threshold1Color": "rgba(216, 200, 27, 0.27)", - "threshold2": null, - "threshold2Color": "rgba(234, 112, 112, 0.22)" - }, - "id": 1, + "span": 6, + "editable": true, + "type": "graph", "isNew": true, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": true, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "nullPointMode": "connected", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "span": 12, - "stack": false, - "steppedLine": false, - "alerting": { - "queryRef": "A", - "warnLevel": "> 30", - "critLevel": "> 50", - "title": "desktop visiter alerts", - "description": "Restart the webservers", - "queryRange": "5m", - "aggregator": "avg", - "interval": "10" - }, + "id": 3, "targets": [ { - "hide": false, "refId": "A", - "target": "statsd.fakesite.counters.session_start.desktop.count" + "target": "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)" + } + ], + "datasource": null, + "renderer": "flot", + "yaxes": [ + { + "label": null, + "show": true, + "logBase": 1, + "min": null, + "max": null, + "format": "short" }, { - "hide": false, - "refId": "B", - "target": "statsd.fakesite.counters.session_start.mobile.count" + "label": null, + "show": true, + "logBase": 1, + "min": null, + "max": null, + "format": "short" } ], - "timeFrom": null, - "timeShift": null, - "title": "Panel Title", - "tooltip": { - "msResolution": false, - "shared": true, - "value_type": "cumulative" - }, - "type": "graph", "xaxis": { "show": true }, + "grid": { + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 1, + "linewidth": 2, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": true, + "msResolution": false + }, + "timeFrom": null, + "timeShift": null, + "aliasColors": {}, + "seriesOverrides": [], + "alerting": { + "queryRef": "A", + "warnLevel": "> 30", + "critLevel": "> 50", + "aggregator": "sum", + "queryRange": "10m", + "interval": "10s", + "title": "active desktop users", + "description": "restart webservers" + }, + "links": [] + }, + { + "title": "Active mobile users", + "error": false, + "span": 6, + "editable": true, + "type": "graph", + "isNew": true, + "id": 4, + "targets": [ + { + "refId": "A", + "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)" + } + ], + "datasource": "graphite2", + "renderer": "flot", "yaxes": [ { - "format": "short", + "label": null, + "show": true, "logBase": 1, - "max": null, "min": null, - "show": true + "max": null, + "format": "short" }, { - "format": "short", + "label": null, + "show": true, "logBase": 1, - "max": null, "min": null, - "show": true + "max": null, + "format": "short" } - ] + ], + "xaxis": { + "show": true + }, + "grid": { + "threshold1": null, + "threshold2": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "lines": true, + "fill": 1, + "linewidth": 2, + "points": false, + "pointradius": 5, + "bars": false, + "stack": false, + "percentage": false, + "legend": { + "show": true, + "values": false, + "min": false, + "max": false, + "current": false, + "total": false, + "avg": false + }, + "nullPointMode": "connected", + "steppedLine": false, + "tooltip": { + "value_type": "cumulative", + "shared": true, + "msResolution": false + }, + "timeFrom": null, + "timeShift": null, + "aliasColors": { + "mobile": "#EAB839" + }, + "seriesOverrides": [], + "alerting": { + "queryRef": "A", + "warnLevel": "> 300", + "critLevel": "> 500", + "aggregator": "avg", + "queryRange": "10m", + "interval": "10s", + "title": "active mobile users", + "description": "restart itunes" + }, + "links": [] } ], "title": "Row" @@ -140,7 +219,7 @@ func TestAlertModel(t *testing.T) { "col": 0, "desc": true }, - "span": 12, + "span": 6, "styles": [ { "dateFormat": "YYYY-MM-DD HH:mm:ss", @@ -201,9 +280,10 @@ func TestAlertModel(t *testing.T) { "target": "" } ], - "title": "Panel Title", + "title": "Broken influxdb panel", "transform": "table", - "type": "table" + "type": "table", + "links": [] } ], "title": "New row" @@ -248,10 +328,9 @@ func TestAlertModel(t *testing.T) { "list": [] }, "schemaVersion": 12, - "version": 20, + "version": 16, "links": [] }` - dashboardJson, _ := simplejson.NewJson([]byte(json)) cmd := &SaveDashboardCommand{ Dashboard: dashboardJson, @@ -267,14 +346,14 @@ func TestAlertModel(t *testing.T) { Convey("all properties have been set", func() { So(alerts, ShouldNotBeEmpty) - So(len(alerts), ShouldEqual, 1) + So(len(alerts), ShouldEqual, 2) for _, v := range alerts { So(v.DashboardId, ShouldEqual, 1) So(v.PanelId, ShouldNotEqual, 0) - So(v.WarnLevel, ShouldEqual, "> 30") - So(v.CritLevel, ShouldEqual, "> 50") + So(v.WarnLevel, ShouldNotBeEmpty) + So(v.CritLevel, ShouldNotBeEmpty) So(v.Aggregator, ShouldNotBeEmpty) So(v.Query, ShouldNotBeEmpty) @@ -282,12 +361,19 @@ func TestAlertModel(t *testing.T) { So(v.QueryRange, ShouldNotBeEmpty) So(v.Title, ShouldNotBeEmpty) So(v.Description, ShouldNotBeEmpty) - So(v.Interval, ShouldEqual, "10") - - fmt.Println(v.Query) } - So(alerts[0].Query, ShouldEqual, "{\"hide\":false,\"refId\":\"A\",\"target\":\"statsd.fakesite.counters.session_start.desktop.count\"}") + So(alerts[0].WarnLevel, ShouldEqual, "> 30") + So(alerts[1].WarnLevel, ShouldEqual, "> 300") + + So(alerts[0].CritLevel, ShouldEqual, "> 50") + So(alerts[1].CritLevel, ShouldEqual, "> 500") + + So(alerts[0].Query, ShouldEqual, `{"refId":"A","target":"aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"}`) + So(alerts[1].Query, ShouldEqual, `{"refId":"A","target":"aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`) + + So(alerts[0].DatasourceName, ShouldEqual, "") + So(alerts[1].DatasourceName, ShouldEqual, "graphite2") }) }) } diff --git a/pkg/services/sqlstore/alerting.go b/pkg/services/sqlstore/alerting.go index b39a5556d0a..e2729431337 100644 --- a/pkg/services/sqlstore/alerting.go +++ b/pkg/services/sqlstore/alerting.go @@ -68,6 +68,7 @@ func alertIsDifferent(rule1, rule2 m.AlertRule) bool { result = result || rule1.Title != rule2.Title result = result || rule1.Description != rule2.Description result = result || rule1.QueryRange != rule2.QueryRange + result = result || rule1.DatasourceName != rule2.DatasourceName return result } diff --git a/pkg/services/sqlstore/alerting_test.go b/pkg/services/sqlstore/alerting_test.go index dec3a94d9a4..aab7b883ffa 100644 --- a/pkg/services/sqlstore/alerting_test.go +++ b/pkg/services/sqlstore/alerting_test.go @@ -16,18 +16,19 @@ func TestAlertingDataAccess(t *testing.T) { items := []m.AlertRule{ { - PanelId: 1, - DashboardId: testDash.Id, - OrgId: testDash.OrgId, - Query: "Query", - QueryRefId: "A", - WarnLevel: "> 30", - CritLevel: "> 50", - Interval: "10", - Title: "Alerting title", - Description: "Alerting description", - QueryRange: "5m", - Aggregator: "avg", + PanelId: 1, + DashboardId: testDash.Id, + OrgId: testDash.OrgId, + Query: "Query", + QueryRefId: "A", + WarnLevel: "> 30", + CritLevel: "> 50", + Interval: "10", + Title: "Alerting title", + Description: "Alerting description", + QueryRange: "5m", + Aggregator: "avg", + DatasourceName: "graphite", }, } @@ -62,6 +63,7 @@ func TestAlertingDataAccess(t *testing.T) { So(alert.Description, ShouldEqual, "Alerting description") So(alert.QueryRange, ShouldEqual, "5m") So(alert.Aggregator, ShouldEqual, "avg") + So(alert.DatasourceName, ShouldEqual, "graphite") }) Convey("Alerts with same dashboard id and panel id should update", func() { diff --git a/pkg/services/sqlstore/migrations/alert_mig.go b/pkg/services/sqlstore/migrations/alert_mig.go index 204e7a855a0..74ed633091e 100644 --- a/pkg/services/sqlstore/migrations/alert_mig.go +++ b/pkg/services/sqlstore/migrations/alert_mig.go @@ -19,6 +19,7 @@ func addAlertMigrations(mg *Migrator) { {Name: "description", Type: DB_NVarchar, Length: 255, Nullable: false}, {Name: "query_range", Type: DB_NVarchar, Length: 255, Nullable: false}, {Name: "aggregator", Type: DB_NVarchar, Length: 255, Nullable: false}, + {Name: "datasource_name", Type: DB_NVarchar, Length: 255, Nullable: false}, }, }