diff --git a/pkg/models/alerts.go b/pkg/models/alerts.go index bc110d8024f..00e7ec0325a 100644 --- a/pkg/models/alerts.go +++ b/pkg/models/alerts.go @@ -1,7 +1,7 @@ package models import ( -//"github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/components/simplejson" ) type Alert struct { @@ -12,7 +12,7 @@ type Alert struct { QueryRefId string WarnLevel int64 ErrorLevel int64 - Interval string + Interval int64 Title string Description string QueryRange string @@ -21,23 +21,36 @@ type Alert struct { func (cmd *SaveDashboardCommand) GetAlertModels() *[]Alert { dash := NewDashboardFromJson(cmd.Dashboard) - alerts := make([]Alert, 0) - alerts = append(alerts, Alert{ - DashboardId: dash.Id, - Id: 1, - PanelId: 1, - Query: "query", - QueryRefId: "query_ref", - WarnLevel: 0, - ErrorLevel: 0, - Interval: "5s", - Title: dash.Title + " Alert", - Description: dash.Title + " Description", - QueryRange: "10m", - Aggregator: "avg", - }) + for _, rowObj := range cmd.Dashboard.Get("rows").MustArray() { + row := simplejson.NewFromAny(rowObj) + + for _, panelObj := range row.Get("panels").MustArray() { + panel := simplejson.NewFromAny(panelObj) + + for _, alertObj := range panel.Get("alerts").MustArray() { + alertDef := simplejson.NewFromAny(alertObj) + + alert := Alert{ + DashboardId: dash.Id, + PanelId: panel.Get("id").MustInt64(), + Id: alertDef.Get("id").MustInt64(), + Query: alertDef.Get("query").MustString(), + QueryRefId: alertDef.Get("query_ref").MustString(), + WarnLevel: alertDef.Get("warn_level").MustInt64(), + ErrorLevel: alertDef.Get("error_level").MustInt64(), + Interval: alertDef.Get("interval").MustInt64(), + Title: alertDef.Get("title").MustString(), + Description: alertDef.Get("description").MustString(), + QueryRange: alertDef.Get("query_range").MustString(), + Aggregator: alertDef.Get("aggregator").MustString(), + } + + alerts = append(alerts, alert) + } + } + } return &alerts } diff --git a/pkg/models/alerts_test.go b/pkg/models/alerts_test.go new file mode 100644 index 00000000000..b01dd716f99 --- /dev/null +++ b/pkg/models/alerts_test.go @@ -0,0 +1,302 @@ +package models + +import ( + "testing" + + "fmt" + "github.com/grafana/grafana/pkg/components/simplejson" + . "github.com/smartystreets/goconvey/convey" +) + +func TestAlertModel(t *testing.T) { + + Convey("Parsing alerts from dashboard", t, func() { + json := `{ + "id": 7, + "title": "Graphite 4", + "originalTitle": "Graphite 4", + "tags": [ + "graphite" + ], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": null, + "editable": true, + "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, + "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, + "alerts": [ + { + "query_ref": "A", + "warn_level": 30, + "error_level": 50, + "title": "desktop visiter alerts", + "description": "Restart the webservers", + "query_range": "5m", + "aggregator": "avg", + "interval": 10 + }, + { + "query_ref": "B", + "warn_level": 30, + "error_level": 50, + "title": "mobile visiter alerts", + "description": "Restart the webservers", + "query_range": "5m", + "aggregator": "avg", + "interval": 10 + } + ], + "targets": [ + { + "hide": false, + "refId": "A", + "target": "statsd.fakesite.counters.session_start.desktop.count" + }, + { + "hide": false, + "refId": "B", + "target": "statsd.fakesite.counters.session_start.mobile.count" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Panel Title", + "tooltip": { + "msResolution": false, + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "Row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "columns": [], + "datasource": "InfluxDB", + "editable": true, + "error": false, + "fontSize": "100%", + "id": 2, + "isNew": true, + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "span": 12, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "cpu", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"cpu\" WHERE $timeFilter GROUP BY time($interval) fill(null)", + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [], + "target": "" + } + ], + "title": "Panel Title", + "transform": "table", + "type": "table" + } + ], + "title": "New row" + } + ], + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "now": true, + "nowDelay": "5m", + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d", + "7d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "schemaVersion": 12, + "version": 20, + "links": [] +}` + + dashboardJson, _ := simplejson.NewJson([]byte(json)) + cmd := &SaveDashboardCommand{ + Dashboard: dashboardJson, + UserId: 1, + OrgId: 1, + Overwrite: true, + } + + alerts := *cmd.GetAlertModels() + + Convey("all properties have been set", func() { + So(alerts, ShouldNotBeEmpty) + So(len(alerts), ShouldEqual, 2) + + for _, v := range alerts { + So(v.DashboardId, ShouldNotEqual, 0) + So(v.PanelId, ShouldNotEqual, 0) + + So(v.WarnLevel, ShouldEqual, 30) + So(v.ErrorLevel, ShouldEqual, 50) + + So(v.Aggregator, ShouldNotBeEmpty) + //So(v.Query, ShouldNotBeEmpty) + So(v.QueryRefId, ShouldNotBeEmpty) + So(v.QueryRange, ShouldNotBeEmpty) + So(v.Title, ShouldNotBeEmpty) + So(v.Description, ShouldNotBeEmpty) + + fmt.Println(v.Query) + } + + //So(alerts[0].Query, ShouldEqual, "statsd.fakesite.counters.session_start.desktop.count") + //So(alerts[1].Query, ShouldEqual, "statsd.fakesite.counters.session_start.mobile.count") + }) + }) +} diff --git a/pkg/services/sqlstore/migrations/alert_mig.go b/pkg/services/sqlstore/migrations/alert_mig.go index 05476633891..2f94a4ec042 100644 --- a/pkg/services/sqlstore/migrations/alert_mig.go +++ b/pkg/services/sqlstore/migrations/alert_mig.go @@ -13,9 +13,9 @@ func addAlertMigrations(mg *Migrator) { {Name: "panel_id", Type: DB_BigInt, Nullable: false}, {Name: "query", Type: DB_Text, Nullable: false}, {Name: "query_ref_id", Type: DB_NVarchar, Length: 255, Nullable: false}, - {Name: "warn_level", Type: DB_NVarchar, Length: 255, Nullable: false}, - {Name: "error_level", Type: DB_NVarchar, Length: 255, Nullable: false}, - {Name: "interval", Type: DB_NVarchar, Length: 255, Nullable: false}, + {Name: "warn_level", Type: DB_BigInt, Length: 255, Nullable: false}, + {Name: "error_level", Type: DB_BigInt, Length: 255, Nullable: false}, + {Name: "interval", Type: DB_BigInt, Length: 255, Nullable: false}, {Name: "title", Type: DB_NVarchar, Length: 255, Nullable: false}, {Name: "description", Type: DB_NVarchar, Length: 255, Nullable: false}, {Name: "query_range", Type: DB_NVarchar, Length: 255, Nullable: false},