From 20fcffb71eed9fb959f05e025fd52666e8c5607e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 19 Jul 2016 16:15:26 +0200 Subject: [PATCH] feat(alerting): working on alerting conditions model --- pkg/services/alerting/alert_rule.go | 79 ++++++++----------- pkg/services/alerting/alert_rule_test.go | 39 ++++----- pkg/services/alerting/conditions.go | 32 ++++++++ pkg/services/alerting/result_handler_test.go | 8 +- .../app/plugins/panel/graph/alert_tab_ctrl.ts | 43 ++++------ .../panel/graph/partials/tab_alerting.html | 55 ++++++------- 6 files changed, 125 insertions(+), 131 deletions(-) create mode 100644 pkg/services/alerting/conditions.go diff --git a/pkg/services/alerting/alert_rule.go b/pkg/services/alerting/alert_rule.go index cc5968eeb70..8a448fb885f 100644 --- a/pkg/services/alerting/alert_rule.go +++ b/pkg/services/alerting/alert_rule.go @@ -4,7 +4,6 @@ import ( "fmt" "regexp" "strconv" - "strings" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/alerting/transformers" @@ -31,6 +30,19 @@ type AlertRule struct { NotificationGroups []int64 } +type AlertRule2 struct { + Id int64 + OrgId int64 + DashboardId int64 + PanelId int64 + Frequency int64 + Name string + Description string + State string + Conditions []AlertCondition + Notifications []int64 +} + var ( ValueFormatRegex = regexp.MustCompile("^\\d+") UnitFormatRegex = regexp.MustCompile("\\w{1}$") @@ -56,7 +68,11 @@ func getTimeDurationStringToSeconds(str string) int64 { } func NewAlertRuleFromDBModel(ruleDef *m.Alert) (*AlertRule, error) { - model := &AlertRule{} + return nil, nil +} + +func NewAlertRuleFromDBModel2(ruleDef *m.Alert) (*AlertRule2, error) { + model := &AlertRule2{} model.Id = ruleDef.Id model.OrgId = ruleDef.OrgId model.Name = ruleDef.Name @@ -64,55 +80,26 @@ func NewAlertRuleFromDBModel(ruleDef *m.Alert) (*AlertRule, error) { model.State = ruleDef.State model.Frequency = ruleDef.Frequency - ngs := ruleDef.Settings.Get("notificationGroups").MustString() - var ids []int64 - for _, v := range strings.Split(ngs, ",") { - id, err := strconv.Atoi(v) - if err == nil { - ids = append(ids, int64(id)) + for _, v := range ruleDef.Settings.Get("notifications").MustArray() { + if id, ok := v.(int64); ok { + model.Notifications = append(model.Notifications, int64(id)) } } - model.NotificationGroups = ids - - critical := ruleDef.Settings.Get("crit") - model.Critical = Level{ - Operator: critical.Get("op").MustString(), - Value: critical.Get("value").MustFloat64(), - } - - warning := ruleDef.Settings.Get("warn") - model.Warning = Level{ - Operator: warning.Get("op").MustString(), - Value: warning.Get("value").MustFloat64(), - } - - model.Transform = ruleDef.Settings.Get("transform").Get("type").MustString() - if model.Transform == "" { - return nil, fmt.Errorf("missing transform") - } - - model.TransformParams = *ruleDef.Settings.Get("transform") - - if model.Transform == "aggregation" { - method := ruleDef.Settings.Get("transform").Get("method").MustString() - model.Transformer = transformers.NewAggregationTransformer(method) - } - - query := ruleDef.Settings.Get("query") - model.Query = AlertQuery{ - Query: query.Get("query").MustString(), - DatasourceId: query.Get("datasourceId").MustInt64(), - From: query.Get("from").MustString(), - To: query.Get("to").MustString(), - } - - if model.Query.Query == "" { - return nil, fmt.Errorf("missing query.query") + for _, condition := range ruleDef.Settings.Get("conditions").MustArray() { + conditionModel := simplejson.NewFromAny(condition) + switch conditionModel.Get("type").MustString() { + case "query": + queryCondition, err := NewQueryCondition(conditionModel) + if err != nil { + return nil, err + } + model.Conditions = append(model.Conditions, queryCondition) + } } - if model.Query.DatasourceId == 0 { - return nil, fmt.Errorf("missing query.datasourceId") + if len(model.Conditions) == 0 { + return nil, fmt.Errorf("Alert is missing conditions") } return model, nil diff --git a/pkg/services/alerting/alert_rule_test.go b/pkg/services/alerting/alert_rule_test.go index 8050dd46aa9..9b75105579d 100644 --- a/pkg/services/alerting/alert_rule_test.go +++ b/pkg/services/alerting/alert_rule_test.go @@ -38,26 +38,19 @@ func TestAlertRuleModel(t *testing.T) { "description": "desc2", "handler": 0, "enabled": true, - "crit": { - "value": 20, - "op": ">" - }, - "warn": { - "value": 10, - "op": ">" - }, "frequency": "60s", - "query": { - "from": "5m", - "refId": "A", - "to": "now", - "query": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)", - "datasourceId": 1 - }, - "transform": { - "type": "avg", - "name": "aggregation" - } + "conditions": [ + { + "type": "query", + "query": { + "params": ["A", "5m", "now"], + "datasourceId": 1, + "query": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)" + }, + "reducer": {"type": "avg", "params": []}, + "evaluator": {"type": ">", "params": [100]} + } + ] } ` @@ -72,15 +65,11 @@ func TestAlertRuleModel(t *testing.T) { Settings: alertJSON, } - alertRule, err := NewAlertRuleFromDBModel(alert) + alertRule, err := NewAlertRuleFromDBModel2(alert) So(err, ShouldBeNil) - So(alertRule.Warning.Operator, ShouldEqual, ">") - So(alertRule.Warning.Value, ShouldEqual, 10) - - So(alertRule.Critical.Operator, ShouldEqual, ">") - So(alertRule.Critical.Value, ShouldEqual, 20) + So(alertRule.Conditions, ShouldHaveLength, 1) }) }) } diff --git a/pkg/services/alerting/conditions.go b/pkg/services/alerting/conditions.go new file mode 100644 index 00000000000..5fea9c81bd6 --- /dev/null +++ b/pkg/services/alerting/conditions.go @@ -0,0 +1,32 @@ +package alerting + +import "github.com/grafana/grafana/pkg/components/simplejson" + +type AlertCondition interface { + Eval() +} + +type QueryCondition struct { + Query AlertQuery + Reducer AlertReducerModel + Evaluator AlertEvaluatorModel +} + +func (c *QueryCondition) Eval() { +} + +type AlertReducerModel struct { + Type string + Params []interface{} +} + +type AlertEvaluatorModel struct { + Type string + Params []interface{} +} + +func NewQueryCondition(model *simplejson.Json) (*QueryCondition, error) { + condition := QueryCondition{} + + return &condition, nil +} diff --git a/pkg/services/alerting/result_handler_test.go b/pkg/services/alerting/result_handler_test.go index f44049ecb6d..99879e52202 100644 --- a/pkg/services/alerting/result_handler_test.go +++ b/pkg/services/alerting/result_handler_test.go @@ -38,7 +38,7 @@ func TestAlertResultHandler(t *testing.T) { Convey("alert state have changed", func() { mockAlertState = &m.AlertState{ - NewState: alertstates.Critical, + State: alertstates.Critical, } mockResult.State = alertstates.Ok So(resultHandler.shouldUpdateState(mockResult), ShouldBeTrue) @@ -47,11 +47,11 @@ func TestAlertResultHandler(t *testing.T) { Convey("last alert state was 15min ago", func() { now := time.Now() mockAlertState = &m.AlertState{ - NewState: alertstates.Critical, - Created: now.Add(time.Minute * -30), + State: alertstates.Critical, + Created: now.Add(time.Minute * -30), } mockResult.State = alertstates.Critical - mockResult.ExeuctionTime = time.Now() + mockResult.StartTime = time.Now() So(resultHandler.shouldUpdateState(mockResult), ShouldBeTrue) }) }) diff --git a/public/app/plugins/panel/graph/alert_tab_ctrl.ts b/public/app/plugins/panel/graph/alert_tab_ctrl.ts index 5779fff73c6..211e08675dd 100644 --- a/public/app/plugins/panel/graph/alert_tab_ctrl.ts +++ b/public/app/plugins/panel/graph/alert_tab_ctrl.ts @@ -38,11 +38,15 @@ export class AlertTabCtrl { ]; alert: any; conditionModels: any; - levelOpList = [ + evalFunctions = [ {text: '>', value: '>'}, {text: '<', value: '<'}, - {text: '=', value: '='}, ]; + severityLevels = [ + {text: 'Critical', value: 'critical'}, + {text: 'Warning', value: 'warning'}, + ]; + /** @ngInject */ constructor($scope, private $timeout) { @@ -60,21 +64,15 @@ export class AlertTabCtrl { }); } - getThresholdWithDefaults(threshold) { - threshold = threshold || {}; - threshold.op = threshold.op || '>'; - threshold.value = threshold.value || undefined; - return threshold; - } - initModel() { var alert = this.alert = this.panel.alert = this.panel.alert || {}; - alert.conditions = alert.conditions || []; + alert.conditions = []; if (alert.conditions.length === 0) { alert.conditions.push(this.buildDefaultCondition()); } + alert.severity = alert.severity || 'critical'; alert.frequency = alert.frequency || '60s'; alert.handler = alert.handler || 1; alert.notifications = alert.notifications || []; @@ -95,32 +93,23 @@ export class AlertTabCtrl { buildDefaultCondition() { return { type: 'query', - refId: 'A', - from: '5m', - to: 'now', - reducer: 'avg', - reducerParams: [], - warn: this.getThresholdWithDefaults({}), - crit: this.getThresholdWithDefaults({}), + query: {params: ['A', '5m', 'now']}, + reducer: {type: 'avg', params: []}, + evaluator: {type: '>', params: [null]}, }; } buildConditionModel(source) { var cm: any = {source: source, type: source.type}; - var queryPartModel = { - params: [source.refId, source.from, source.to] - }; - - cm.queryPart = new QueryPart(queryPartModel, alertQueryDef); + cm.queryPart = new QueryPart(source.query, alertQueryDef); cm.reducerPart = new QueryPart({params: []}, reducerAvgDef); + cm.evaluator = source.evaluator; + return cm; } queryPartUpdated(conditionModel) { - conditionModel.source.refId = conditionModel.queryPart.params[0]; - conditionModel.source.from = conditionModel.queryPart.params[1]; - conditionModel.source.to = conditionModel.queryPart.params[2]; } addCondition(type) { @@ -138,10 +127,6 @@ export class AlertTabCtrl { delete() { this.alert.enabled = false; - this.alert.warn.value = undefined; - this.alert.crit.value = undefined; - - // reset model but keep thresholds instance this.initModel(); } diff --git a/public/app/plugins/panel/graph/partials/tab_alerting.html b/public/app/plugins/panel/graph/partials/tab_alerting.html index 6d07173fe24..377c6aad3ea 100644 --- a/public/app/plugins/panel/graph/partials/tab_alerting.html +++ b/public/app/plugins/panel/graph/partials/tab_alerting.html @@ -27,31 +27,42 @@
Alert Rule
-
+
Name
-
- Handler -
- -
-
+ + + + + + + + +
Evaluate every
-
- Notifications - +
+
+ Notifications + +
+
+ Severity +
+ +
+
@@ -59,7 +70,7 @@
Conditions
- {{$index+1}} + AND
- - - Critcal if - - - + When Value + +
- - - Warn if - - - -