Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
3219d98a
Commit
3219d98a
authored
Jul 20, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(alerting): starting work on condition evaluation
parent
f872d5cf
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
198 additions
and
156 deletions
+198
-156
pkg/services/alerting/conditions_test.go
+40
-0
pkg/services/alerting/engine.go
+1
-1
pkg/services/alerting/extractor.go
+1
-0
pkg/services/alerting/handler.go
+10
-0
pkg/services/alerting/handler_test.go
+145
-154
pkg/services/alerting/interfaces.go
+1
-1
No files found.
pkg/services/alerting/conditions_test.go
0 → 100644
View file @
3219d98a
package
alerting
import
(
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
.
"github.com/smartystreets/goconvey/convey"
)
func
TestQueryCondition
(
t
*
testing
.
T
)
{
Convey
(
"when evaluating query condition"
,
t
,
func
()
{
Convey
(
"Given avg() and > 100"
,
func
()
{
jsonModel
,
err
:=
simplejson
.
NewJson
([]
byte
(
`{
"type": "query",
"query": {
"params": ["A", "5m", "now"],
"datasourceId": 1,
"model": {"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
},
"reducer": {"type": "avg", "params": []},
"evaluator": {"type": ">", "params": [100]}
}`
))
So
(
err
,
ShouldBeNil
)
condition
,
err
:=
NewQueryCondition
(
jsonModel
)
So
(
err
,
ShouldBeNil
)
Convey
(
"Should set result to triggered when avg is above 100"
,
func
()
{
context
:=
&
AlertResultContext
{}
condition
.
Eval
(
context
)
So
(
context
.
Triggered
,
ShouldBeTrue
)
})
})
})
}
pkg/services/alerting/engine.go
View file @
3219d98a
...
...
@@ -14,7 +14,7 @@ type Engine struct {
clock
clock
.
Clock
ticker
*
Ticker
scheduler
Scheduler
handler
Alert
ing
Handler
handler
AlertHandler
ruleReader
RuleReader
log
log
.
Logger
responseHandler
ResultHandler
...
...
pkg/services/alerting/extractor.go
View file @
3219d98a
...
...
@@ -90,6 +90,7 @@ func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) {
Handler
:
jsonAlert
.
Get
(
"handler"
)
.
MustInt64
(),
Enabled
:
jsonAlert
.
Get
(
"enabled"
)
.
MustBool
(),
Description
:
jsonAlert
.
Get
(
"description"
)
.
MustString
(),
Severity
:
jsonAlert
.
Get
(
"severity"
)
.
MustString
(),
Frequency
:
getTimeDurationStringToSeconds
(
jsonAlert
.
Get
(
"frequency"
)
.
MustString
()),
}
...
...
pkg/services/alerting/handler.go
View file @
3219d98a
...
...
@@ -31,6 +31,16 @@ func (e *HandlerImpl) eval(rule *AlertRule) *AlertResultContext {
for
_
,
condition
:=
range
rule
.
Conditions
{
condition
.
Eval
(
result
)
// break if condition could not be evaluated
if
result
.
Error
!=
nil
{
break
}
// break if result has not triggered yet
if
result
.
Triggered
==
false
{
break
}
}
result
.
EndTime
=
time
.
Now
()
...
...
pkg/services/alerting/handler_test.go
View file @
3219d98a
...
...
@@ -3,171 +3,162 @@ package alerting
import
(
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
.
"github.com/smartystreets/goconvey/convey"
)
type
conditionStub
struct
{
triggered
bool
}
func
(
c
*
conditionStub
)
Eval
(
context
*
AlertResultContext
)
{
context
.
Triggered
=
c
.
triggered
}
func
TestAlertingExecutor
(
t
*
testing
.
T
)
{
Convey
(
"Test alert execution"
,
t
,
func
()
{
handler
:=
NewHandler
()
Convey
(
"single time serie"
,
func
()
{
Convey
(
"Show return ok since avg is above 2"
,
func
()
{
json
:=
`
{
"name": "name2",
"description": "desc2",
"handler": 0,
"enabled": true,
"frequency": "60s",
"conditions": [
{
"type": "query",
"query": {
"params": ["A", "5m", "now"],
"datasourceId": 1,
"model": {"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
},
"reducer": {"type": "avg", "params": []},
"evaluator": {"type": ">", "params": [100]}
}
]
Convey
(
"Show return triggered with single passing condition"
,
func
()
{
rule
:=
&
AlertRule
{
Conditions
:
[]
AlertCondition
{
&
conditionStub
{
triggered
:
true
,
}},
}
`
alertJSON
,
jsonErr
:=
simplejson
.
NewJson
([]
byte
(
json
))
So
(
jsonErr
,
ShouldBeNil
)
alert
:=
&
models
.
Alert
{
Settings
:
alertJSON
}
rule
,
_
:=
NewAlertRuleFromDBModel
(
alert
)
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// }
result
:=
handler
.
eval
(
rule
)
So
(
result
.
Triggered
,
ShouldEqual
,
true
)
})
result
:=
handler
.
eval
(
rule
)
So
(
result
.
Triggered
,
ShouldEqual
,
true
)
})
Convey
(
"Show return false with not passing condition"
,
func
()
{
rule
:=
&
AlertRule
{
Conditions
:
[]
AlertCondition
{
&
conditionStub
{
triggered
:
true
},
&
conditionStub
{
triggered
:
false
},
},
}
// Convey("Show return critical since below 2", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: "<"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// Convey("Show return critical since sum is above 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("sum"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{9, 0}, {9, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// Convey("Show return ok since avg is below 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{9, 0}, {9, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Ok)
// })
//
// Convey("Show return ok since min is below 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{11, 0}, {9, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Ok)
// })
//
// Convey("Show return ok since max is above 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("max"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{6, 0}, {11, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// })
//
// Convey("muliple time series", func() {
// Convey("both are ok", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Ok)
// })
//
// Convey("first serie is good, second is critical", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// tsdb.NewTimeSeries("test1", [][2]float64{{11, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// Convey("first serie is warn, second is critical", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Warning: Level{Value: 5, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{6, 0}}),
// tsdb.NewTimeSeries("test1", [][2]float64{{11, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
result
:=
handler
.
eval
(
rule
)
So
(
result
.
Triggered
,
ShouldEqual
,
false
)
})
// Convey("Show return critical since below 2", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: "<"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// Convey("Show return critical since sum is above 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("sum"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{9, 0}, {9, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// Convey("Show return ok since avg is below 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{9, 0}, {9, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Ok)
// })
//
// Convey("Show return ok since min is below 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{11, 0}, {9, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Ok)
// })
//
// Convey("Show return ok since max is above 10", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("max"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{6, 0}, {11, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// })
//
// Convey("muliple time series", func() {
// Convey("both are ok", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Ok)
// })
//
// Convey("first serie is good, second is critical", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{2, 0}}),
// tsdb.NewTimeSeries("test1", [][2]float64{{11, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
//
// Convey("first serie is warn, second is critical", func() {
// rule := &AlertRule{
// Critical: Level{Value: 10, Operator: ">"},
// Warning: Level{Value: 5, Operator: ">"},
// Transformer: transformers.NewAggregationTransformer("avg"),
// }
//
// timeSeries := []*tsdb.TimeSeries{
// tsdb.NewTimeSeries("test1", [][2]float64{{6, 0}}),
// tsdb.NewTimeSeries("test1", [][2]float64{{11, 0}}),
// }
//
// result := executor.evaluateRule(rule, timeSeries)
// So(result.State, ShouldEqual, alertstates.Critical)
// })
// })
})
}
pkg/services/alerting/interfaces.go
View file @
3219d98a
...
...
@@ -2,7 +2,7 @@ package alerting
import
"time"
type
Alert
ing
Handler
interface
{
type
AlertHandler
interface
{
Execute
(
rule
*
AlertRule
,
resultChan
chan
*
AlertResultContext
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment