feat(alerting): working on alerting conditions model
This commit is contained in:
@@ -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(),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user