Просмотр исходного кода

feat(alerting): progress on refactoring backend alert rule model

Torkel Ödegaard 9 лет назад
Родитель
Сommit
f60efed5d8

+ 22 - 1
pkg/services/alerting/alert_rule_test.go

@@ -31,7 +31,7 @@ func TestAlertRuleModel(t *testing.T) {
 			So(seconds, ShouldEqual, 1)
 		})
 
-		Convey("", func() {
+		Convey("can construct alert rule model", func() {
 			json := `
 			{
 				"name": "name2",
@@ -70,6 +70,27 @@ func TestAlertRuleModel(t *testing.T) {
 			So(err, ShouldBeNil)
 
 			So(alertRule.Conditions, ShouldHaveLength, 1)
+
+			Convey("Can read query condition from json model", func() {
+				queryCondition, ok := alertRule.Conditions[0].(*QueryCondition)
+				So(ok, ShouldBeTrue)
+
+				So(queryCondition.Query.From, ShouldEqual, "5m")
+				So(queryCondition.Query.To, ShouldEqual, "now")
+				So(queryCondition.Query.DatasourceId, ShouldEqual, 1)
+
+				Convey("Can read query reducer", func() {
+					reducer, ok := queryCondition.Reducer.(*SimpleReducer)
+					So(ok, ShouldBeTrue)
+					So(reducer.Type, ShouldEqual, "avg")
+				})
+
+				Convey("Can read evaluator", func() {
+					evaluator, ok := queryCondition.Evaluator.(*DefaultAlertEvaluator)
+					So(ok, ShouldBeTrue)
+					So(evaluator.Type, ShouldEqual, ">")
+				})
+			})
 		})
 	})
 }

+ 66 - 15
pkg/services/alerting/conditions.go

@@ -1,32 +1,83 @@
 package alerting
 
-import "github.com/grafana/grafana/pkg/components/simplejson"
+import (
+	"encoding/json"
+	"errors"
 
-type AlertCondition interface {
-	Eval()
-}
+	"github.com/grafana/grafana/pkg/components/simplejson"
+)
 
 type QueryCondition struct {
 	Query     AlertQuery
-	Reducer   AlertReducerModel
-	Evaluator AlertEvaluatorModel
+	Reducer   QueryReducer
+	Evaluator AlertEvaluator
 }
 
 func (c *QueryCondition) Eval() {
 }
 
-type AlertReducerModel struct {
-	Type   string
-	Params []interface{}
+func NewQueryCondition(model *simplejson.Json) (*QueryCondition, error) {
+	condition := QueryCondition{}
+
+	queryJson := model.Get("query")
+
+	condition.Query.Query = queryJson.Get("query").MustString()
+	condition.Query.From = queryJson.Get("params").MustArray()[1].(string)
+	condition.Query.To = queryJson.Get("params").MustArray()[2].(string)
+	condition.Query.DatasourceId = queryJson.Get("datasourceId").MustInt64()
+
+	reducerJson := model.Get("reducer")
+	condition.Reducer = NewSimpleReducer(reducerJson.Get("type").MustString())
+
+	evaluatorJson := model.Get("evaluator")
+	evaluator, err := NewDefaultAlertEvaluator(evaluatorJson)
+	if err != nil {
+		return nil, err
+	}
+
+	condition.Evaluator = evaluator
+	return &condition, nil
 }
 
-type AlertEvaluatorModel struct {
-	Type   string
-	Params []interface{}
+type SimpleReducer struct {
+	Type string
 }
 
-func NewQueryCondition(model *simplejson.Json) (*QueryCondition, error) {
-	condition := QueryCondition{}
+func (s *SimpleReducer) Reduce() float64 {
+	return 0
+}
 
-	return &condition, nil
+func NewSimpleReducer(typ string) *SimpleReducer {
+	return &SimpleReducer{Type: typ}
+}
+
+type DefaultAlertEvaluator struct {
+	Type      string
+	Threshold float64
+}
+
+func (e *DefaultAlertEvaluator) Eval() bool {
+	return true
+}
+
+func NewDefaultAlertEvaluator(model *simplejson.Json) (*DefaultAlertEvaluator, error) {
+	evaluator := &DefaultAlertEvaluator{}
+
+	evaluator.Type = model.Get("type").MustString()
+	if evaluator.Type == "" {
+		return nil, errors.New("Alert evaluator missing type property")
+	}
+
+	params := model.Get("params").MustArray()
+	if len(params) == 0 {
+		return nil, errors.New("Alert evaluator missing threshold parameter")
+	}
+
+	threshold, ok := params[0].(json.Number)
+	if !ok {
+		return nil, errors.New("Alert evaluator has invalid threshold parameter")
+	}
+
+	evaluator.Threshold, _ = threshold.Float64()
+	return evaluator, nil
 }

+ 12 - 0
pkg/services/alerting/interfaces.go

@@ -14,3 +14,15 @@ type Scheduler interface {
 type Notifier interface {
 	Notify(alertResult *AlertResult)
 }
+
+type AlertCondition interface {
+	Eval()
+}
+
+type QueryReducer interface {
+	Reduce() float64
+}
+
+type AlertEvaluator interface {
+	Eval() bool
+}