feat(alerting): progress on updating extractor to work with new alert model

This commit is contained in:
Torkel Ödegaard 2016-07-19 21:00:41 +02:00
parent f60efed5d8
commit 2a30baef05
3 changed files with 101 additions and 171 deletions

View File

@ -45,7 +45,7 @@ func TestAlertRuleModel(t *testing.T) {
"query": { "query": {
"params": ["A", "5m", "now"], "params": ["A", "5m", "now"],
"datasourceId": 1, "datasourceId": 1,
"query": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)" "model": {"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
}, },
"reducer": {"type": "avg", "params": []}, "reducer": {"type": "avg", "params": []},
"evaluator": {"type": ">", "params": [100]} "evaluator": {"type": ">", "params": [100]}

View File

@ -2,6 +2,7 @@ package alerting
import ( import (
"errors" "errors"
"fmt"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
@ -47,6 +48,17 @@ func (e *DashAlertExtractor) lookupDatasourceId(dsName string) (*m.DataSource, e
return nil, errors.New("Could not find datasource id for " + dsName) return nil, errors.New("Could not find datasource id for " + dsName)
} }
func findPanelQueryByRefId(panel *simplejson.Json, refId string) *simplejson.Json {
for _, targetsObj := range panel.Get("targets").MustArray() {
target := simplejson.NewFromAny(targetsObj)
if target.Get("refId").MustString() == refId {
return target
}
}
return nil
}
func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) { func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) {
e.log.Debug("GetAlerts") e.log.Debug("GetAlerts")
@ -81,31 +93,31 @@ func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) {
Frequency: getTimeDurationStringToSeconds(jsonAlert.Get("frequency").MustString()), Frequency: getTimeDurationStringToSeconds(jsonAlert.Get("frequency").MustString()),
} }
valueQuery := jsonAlert.Get("query") for _, condition := range jsonAlert.Get("conditions").MustArray() {
valueQueryRef := valueQuery.Get("refId").MustString() jsonCondition := simplejson.NewFromAny(condition)
for _, targetsObj := range panel.Get("targets").MustArray() {
target := simplejson.NewFromAny(targetsObj)
if target.Get("refId").MustString() == valueQueryRef { jsonQuery := jsonCondition.Get("query")
dsName := "" queryRefId := jsonQuery.Get("params").MustArray()[0].(string)
if target.Get("datasource").MustString() != "" { panelQuery := findPanelQueryByRefId(panel, queryRefId)
dsName = target.Get("datasource").MustString()
} else if panel.Get("datasource").MustString() != "" {
dsName = panel.Get("datasource").MustString()
}
if datasource, err := e.lookupDatasourceId(dsName); err != nil { if panelQuery == nil {
return nil, err return nil, fmt.Errorf("Alert referes to query %s, that could not be found", queryRefId)
} else {
valueQuery.SetPath([]string{"datasourceId"}, datasource.Id)
valueQuery.SetPath([]string{"datasourceType"}, datasource.Type)
}
targetQuery := target.Get("target").MustString()
if targetQuery != "" {
jsonAlert.SetPath([]string{"query", "query"}, targetQuery)
}
} }
dsName := ""
if panelQuery.Get("datasource").MustString() != "" {
dsName = panelQuery.Get("datasource").MustString()
} else if panel.Get("datasource").MustString() != "" {
dsName = panel.Get("datasource").MustString()
}
if datasource, err := e.lookupDatasourceId(dsName); err != nil {
return nil, err
} else {
jsonQuery.SetPath([]string{"datasourceId"}, datasource.Id)
}
jsonQuery.Set("model", panelQuery.Interface())
} }
alert.Settings = jsonAlert alert.Settings = jsonAlert
@ -118,7 +130,6 @@ func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) {
e.log.Error("Failed to extract alerts from dashboard", "error", err) e.log.Error("Failed to extract alerts from dashboard", "error", err)
return nil, errors.New("Failed to extract alerts from dashboard") return nil, errors.New("Failed to extract alerts from dashboard")
} }
} }
} }

View File

@ -14,162 +14,69 @@ func TestAlertRuleExtraction(t *testing.T) {
Convey("Parsing alert rules from dashboard json", t, func() { Convey("Parsing alert rules from dashboard json", t, func() {
Convey("Parsing and validating alerts from dashboards", func() { Convey("Parsing and validating alerts from dashboards", func() {
json := `{ json := `{
"id": 57, "id": 57,
"title": "Graphite 4", "title": "Graphite 4",
"originalTitle": "Graphite 4", "originalTitle": "Graphite 4",
"tags": [ "tags": ["graphite"],
"graphite" "rows": [
],
"rows": [
{
"panels": [
{ {
"title": "Active desktop users", "panels": [
"editable": true, {
"type": "graph", "title": "Active desktop users",
"id": 3, "editable": true,
"targets": [ "type": "graph",
"id": 3,
"targets": [
{ {
"refId": "A", "refId": "A",
"target": "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)" "target": "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"
} }
], ],
"datasource": null, "datasource": null,
"alert": { "alert": {
"name": "name1", "name": "name1",
"description": "desc1", "description": "desc1",
"handler": 1, "handler": 1,
"enabled": true, "enabled": true,
"critical": { "frequency": "60s",
"value": 20, "conditions": [
"op": ">" {
}, "type": "query",
"frequency": "60s", "query": {"params": ["A", "5m", "now"]},
"query": { "reducer": {"type": "avg", "params": []},
"from": "5m", "evaluator": {"type": ">", "params": [100]}
"refId": "A", }
"to": "now" ]
},
"transform": {
"type": "avg",
"name": "aggregation"
},
"warn": {
"value": 10,
"op": ">"
}
}
},
{
"title": "Active mobile users",
"id": 4,
"targets": [
{
"refId": "A",
"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"
}
],
"datasource": "graphite2",
"alert": {
"name": "name2",
"description": "desc2",
"handler": 0,
"enabled": true,
"critical": {
"value": 20,
"op": ">"
},
"frequency": "60s",
"query": {
"from": "5m",
"refId": "A",
"to": "now"
},
"transform": {
"type": "avg",
"name": "aggregation"
},
"warn": {
"value": 10,
"op": ">"
}
}
}
],
"title": "Row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"datasource": "InfluxDB",
"id": 2,
"alert": {
"name": "name2",
"description": "desc2",
"enabled": false,
"critical": {
"level": 20,
"op": ">"
},
"warn": {
"level": 10,
"op": ">"
} }
}, },
"targets": [ {
{ "title": "Active mobile users",
"dsType": "influxdb", "id": 4,
"groupBy": [ "targets": [
{ {"refId": "A", "target": ""},
"params": [ {"refId": "B", "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
"$interval" ],
], "datasource": "graphite2",
"type": "time" "alert": {
}, "name": "name2",
{ "description": "desc2",
"params": [ "handler": 0,
"null" "enabled": true,
], "frequency": "60s",
"type": "fill" "conditions": [
} {
], "type": "query",
"measurement": "cpu", "query": {"params": ["B", "5m", "now"]},
"policy": "default", "reducer": {"type": "avg", "params": []},
"query": "SELECT mean(\"value\") FROM \"cpu\" WHERE $timeFilter GROUP BY time($interval) fill(null)", "evaluator": {"type": ">", "params": [100]}
"refId": "A", }
"resultFormat": "table", ]
"select": [
[
{
"params": [
"value"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [],
"target": ""
} }
], }
"title": "Broken influxdb panel", ]
"transform": "table",
"type": "table"
} }
], ]
"title": "New row" }`
}
]
}`
dashJson, err := simplejson.NewJson([]byte(json)) dashJson, err := simplejson.NewJson([]byte(json))
So(err, ShouldBeNil) So(err, ShouldBeNil)
@ -231,6 +138,18 @@ func TestAlertRuleExtraction(t *testing.T) {
So(alerts[1].Name, ShouldEqual, "name2") So(alerts[1].Name, ShouldEqual, "name2")
So(alerts[1].Description, ShouldEqual, "desc2") So(alerts[1].Description, ShouldEqual, "desc2")
}) })
Convey("should set datasourceId", func() {
condition := simplejson.NewFromAny(alerts[0].Settings.Get("conditions").MustArray()[0])
query := condition.Get("query")
So(query.Get("datasourceId").MustInt64(), ShouldEqual, 12)
})
Convey("should copy query model to condition", func() {
condition := simplejson.NewFromAny(alerts[0].Settings.Get("conditions").MustArray()[0])
model := condition.Get("query").Get("model")
So(model.Get("target").MustString(), ShouldEqual, "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)")
})
}) })
}) })
}) })