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
457ae743
Commit
457ae743
authored
Nov 17, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'or_alerting' of
https://github.com/utkarshcmu/grafana
into utkarshcmu-or_alerting
parents
42167a65
aae33b36
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
133 additions
and
12 deletions
+133
-12
docs/sources/alerting/rules.md
+4
-1
pkg/api/alerting.go
+2
-1
pkg/api/dtos/alerting.go
+1
-0
pkg/services/alerting/conditions/query.go
+7
-1
pkg/services/alerting/eval_context.go
+1
-0
pkg/services/alerting/eval_handler.go
+18
-5
pkg/services/alerting/eval_handler_test.go
+88
-3
pkg/services/alerting/interfaces.go
+1
-0
public/app/features/alerting/alert_def.ts
+6
-0
public/app/features/alerting/alert_tab_ctrl.ts
+4
-0
public/app/features/alerting/partials/alert_tab.html
+1
-1
No files found.
docs/sources/alerting/rules.md
View file @
457ae743
...
...
@@ -55,7 +55,10 @@ Currently the only condition type that exists is a `Query` condition that allows
specify a query letter, time range and an aggregation function. The letter refers to
a query you already have added in the
**Metrics**
tab. The result from the query and the aggregation function is
a single value that is then used in the threshold check. The query used in an alert rule cannot
contain any template variables. Currently we only support
`AND`
operator between conditions.
contain any template variables. Currently we only support
`AND`
and
`OR`
operators between conditions and they are executed serially.
For example, we have 3 conditions in the following order:
`condition:A(evaluates to: TRUE) OR condition:B(evaluates to: FALSE) AND condition:C(evaluates to: TRUE)`
so the result will be calculated as ((TRUE OR FALSE) AND TRUE) = TRUE.
We plan to add other condition types in the future, like
`Other Alert`
, where you can include the state
of another alert in your conditions, and
`Time Of Day`
.
...
...
pkg/api/alerting.go
View file @
457ae743
...
...
@@ -119,7 +119,8 @@ func AlertTest(c *middleware.Context, dto dtos.AlertTestCommand) Response {
res
:=
backendCmd
.
Result
dtoRes
:=
&
dtos
.
AlertTestResult
{
Firing
:
res
.
Firing
,
Firing
:
res
.
Firing
,
FiringEval
:
res
.
FiringEval
,
}
if
res
.
Error
!=
nil
{
...
...
pkg/api/dtos/alerting.go
View file @
457ae743
...
...
@@ -36,6 +36,7 @@ type AlertTestCommand struct {
type
AlertTestResult
struct
{
Firing
bool
`json:"firing"`
FiringEval
string
`json:"firingEvaluation"`
TimeMs
string
`json:"timeMs"`
Error
string
`json:"error,omitempty"`
EvalMatches
[]
*
EvalMatch
`json:"matches,omitempty"`
...
...
pkg/services/alerting/conditions/query.go
View file @
457ae743
...
...
@@ -23,6 +23,7 @@ type QueryCondition struct {
Query
AlertQuery
Reducer
QueryReducer
Evaluator
AlertEvaluator
Operator
string
HandleRequest
tsdb
.
HandleRequestFunc
}
...
...
@@ -72,6 +73,7 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.Conditio
return
&
alerting
.
ConditionResult
{
Firing
:
evalMatchCount
>
0
,
NoDataFound
:
emptySerieCount
==
len
(
seriesList
),
Operator
:
c
.
Operator
,
EvalMatches
:
matches
,
},
nil
}
...
...
@@ -168,8 +170,12 @@ func NewQueryCondition(model *simplejson.Json, index int) (*QueryCondition, erro
if
err
!=
nil
{
return
nil
,
err
}
condition
.
Evaluator
=
evaluator
operatorJson
:=
model
.
Get
(
"operator"
)
operator
:=
operatorJson
.
Get
(
"type"
)
.
MustString
()
condition
.
Operator
=
operator
return
&
condition
,
nil
}
...
...
pkg/services/alerting/eval_context.go
View file @
457ae743
...
...
@@ -18,6 +18,7 @@ type EvalContext struct {
Logs
[]
*
ResultLogEntry
Error
error
Description
string
FiringEval
string
StartTime
time
.
Time
EndTime
time
.
Time
Rule
*
Rule
...
...
pkg/services/alerting/eval_handler.go
View file @
457ae743
package
alerting
import
(
"strconv"
"time"
"github.com/grafana/grafana/pkg/log"
...
...
@@ -21,7 +22,9 @@ func NewEvalHandler() *DefaultEvalHandler {
func
(
e
*
DefaultEvalHandler
)
Eval
(
context
*
EvalContext
)
{
firing
:=
true
for
_
,
condition
:=
range
context
.
Rule
.
Conditions
{
firingEval
:=
""
for
i
:=
0
;
i
<
len
(
context
.
Rule
.
Conditions
);
i
++
{
condition
:=
context
.
Rule
.
Conditions
[
i
]
cr
,
err
:=
condition
.
Eval
(
context
)
if
err
!=
nil
{
context
.
Error
=
err
...
...
@@ -32,15 +35,25 @@ func (e *DefaultEvalHandler) Eval(context *EvalContext) {
break
}
// break if result has not triggered yet
if
cr
.
Firing
==
false
{
firing
=
false
break
// calculating Firing based on operator
operator
:=
"AND"
if
cr
.
Operator
==
"or"
{
firing
=
firing
||
cr
.
Firing
operator
=
"OR"
}
else
{
firing
=
firing
&&
cr
.
Firing
}
if
i
>
0
{
firingEval
=
"["
+
firingEval
+
" "
+
operator
+
" "
+
strconv
.
FormatBool
(
cr
.
Firing
)
+
"]"
}
else
{
firingEval
=
strconv
.
FormatBool
(
firing
)
}
context
.
EvalMatches
=
append
(
context
.
EvalMatches
,
cr
.
EvalMatches
...
)
}
context
.
FiringEval
=
firingEval
+
" = "
+
strconv
.
FormatBool
(
firing
)
context
.
Firing
=
firing
context
.
EndTime
=
time
.
Now
()
elapsedTime
:=
context
.
EndTime
.
Sub
(
context
.
StartTime
)
/
time
.
Millisecond
...
...
pkg/services/alerting/eval_handler_test.go
View file @
457ae743
...
...
@@ -8,12 +8,13 @@ import (
)
type
conditionStub
struct
{
firing
bool
matches
[]
*
EvalMatch
firing
bool
operator
string
matches
[]
*
EvalMatch
}
func
(
c
*
conditionStub
)
Eval
(
context
*
EvalContext
)
(
*
ConditionResult
,
error
)
{
return
&
ConditionResult
{
Firing
:
c
.
firing
,
EvalMatches
:
c
.
matches
},
nil
return
&
ConditionResult
{
Firing
:
c
.
firing
,
EvalMatches
:
c
.
matches
,
Operator
:
c
.
operator
},
nil
}
func
TestAlertingExecutor
(
t
*
testing
.
T
)
{
...
...
@@ -29,6 +30,7 @@ func TestAlertingExecutor(t *testing.T) {
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
true
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"true = true"
)
})
Convey
(
"Show return false with not passing asdf"
,
func
()
{
...
...
@@ -41,6 +43,89 @@ func TestAlertingExecutor(t *testing.T) {
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
false
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[true AND false] = false"
)
})
Convey
(
"Show return true if any of the condition is passing with OR operator"
,
func
()
{
context
:=
NewEvalContext
(
context
.
TODO
(),
&
Rule
{
Conditions
:
[]
Condition
{
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"or"
},
},
})
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
true
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[true OR false] = true"
)
})
Convey
(
"Show return false if any of the condition is failing with AND operator"
,
func
()
{
context
:=
NewEvalContext
(
context
.
TODO
(),
&
Rule
{
Conditions
:
[]
Condition
{
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"and"
},
},
})
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
false
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[true AND false] = false"
)
})
Convey
(
"Show return true if one condition is failing with nested OR operator"
,
func
()
{
context
:=
NewEvalContext
(
context
.
TODO
(),
&
Rule
{
Conditions
:
[]
Condition
{
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"or"
},
},
})
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
true
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[[true AND true] OR false] = true"
)
})
Convey
(
"Show return false if one condition is passing with nested OR operator"
,
func
()
{
context
:=
NewEvalContext
(
context
.
TODO
(),
&
Rule
{
Conditions
:
[]
Condition
{
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"or"
},
},
})
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
false
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[[true AND false] OR false] = false"
)
})
Convey
(
"Show return false if a condition is failing with nested AND operator"
,
func
()
{
context
:=
NewEvalContext
(
context
.
TODO
(),
&
Rule
{
Conditions
:
[]
Condition
{
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"and"
},
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
},
})
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
false
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[[true AND false] AND true] = false"
)
})
Convey
(
"Show return true if a condition is passing with nested OR operator"
,
func
()
{
context
:=
NewEvalContext
(
context
.
TODO
(),
&
Rule
{
Conditions
:
[]
Condition
{
&
conditionStub
{
firing
:
true
,
operator
:
"and"
},
&
conditionStub
{
firing
:
false
,
operator
:
"or"
},
&
conditionStub
{
firing
:
true
,
operator
:
"or"
},
},
})
handler
.
Eval
(
context
)
So
(
context
.
Firing
,
ShouldEqual
,
true
)
So
(
context
.
FiringEval
,
ShouldEqual
,
"[[true OR false] OR true] = true"
)
})
})
}
pkg/services/alerting/interfaces.go
View file @
457ae743
...
...
@@ -24,6 +24,7 @@ type Notifier interface {
type
ConditionResult
struct
{
Firing
bool
NoDataFound
bool
Operator
string
EvalMatches
[]
*
EvalMatch
}
...
...
public/app/features/alerting/alert_def.ts
View file @
457ae743
...
...
@@ -28,6 +28,11 @@ var evalFunctions = [
{
text
:
'HAS NO VALUE'
,
value
:
'no_value'
}
];
var
evalOperators
=
[
{
text
:
'OR'
,
value
:
'or'
},
{
text
:
'AND'
,
value
:
'and'
},
];
var
reducerTypes
=
[
{
text
:
'avg()'
,
value
:
'avg'
},
{
text
:
'min()'
,
value
:
'min'
},
...
...
@@ -116,6 +121,7 @@ export default {
getStateDisplayModel
:
getStateDisplayModel
,
conditionTypes
:
conditionTypes
,
evalFunctions
:
evalFunctions
,
evalOperators
:
evalOperators
,
noDataModes
:
noDataModes
,
executionErrorModes
:
executionErrorModes
,
reducerTypes
:
reducerTypes
,
...
...
public/app/features/alerting/alert_tab_ctrl.ts
View file @
457ae743
...
...
@@ -18,6 +18,7 @@ export class AlertTabCtrl {
alert
:
any
;
conditionModels
:
any
;
evalFunctions
:
any
;
evalOperators
:
any
;
noDataModes
:
any
;
executionErrorModes
:
any
;
addNotificationSegment
;
...
...
@@ -41,6 +42,7 @@ export class AlertTabCtrl {
this
.
$scope
.
ctrl
=
this
;
this
.
subTabIndex
=
0
;
this
.
evalFunctions
=
alertDef
.
evalFunctions
;
this
.
evalOperators
=
alertDef
.
evalOperators
;
this
.
conditionTypes
=
alertDef
.
conditionTypes
;
this
.
noDataModes
=
alertDef
.
noDataModes
;
this
.
executionErrorModes
=
alertDef
.
executionErrorModes
;
...
...
@@ -194,6 +196,7 @@ export class AlertTabCtrl {
query
:
{
params
:
[
'A'
,
'5m'
,
'now'
]},
reducer
:
{
type
:
'avg'
,
params
:
[]},
evaluator
:
{
type
:
'gt'
,
params
:
[
null
]},
operator
:
{
type
:
'and'
},
};
}
...
...
@@ -250,6 +253,7 @@ export class AlertTabCtrl {
cm
.
queryPart
=
new
QueryPart
(
source
.
query
,
alertDef
.
alertQueryDef
);
cm
.
reducerPart
=
alertDef
.
createReducerPart
(
source
.
reducer
);
cm
.
evaluator
=
source
.
evaluator
;
cm
.
operator
=
source
.
operator
;
return
cm
;
}
...
...
public/app/features/alerting/partials/alert_tab.html
View file @
457ae743
...
...
@@ -38,7 +38,7 @@
<h5
class=
"section-heading"
>
Conditions
</h5>
<div
class=
"gf-form-inline"
ng-repeat=
"conditionModel in ctrl.conditionModels"
>
<div
class=
"gf-form"
>
<
span
class=
"gf-form-label query-keyword width-5"
ng-if=
"$index"
>
AND
</span
>
<
metric-segment-model
css-class=
"query-keyword"
ng-if=
"$index"
property=
"conditionModel.operator.type"
options=
"ctrl.evalOperators"
custom=
"false"
></metric-segment-model
>
<span
class=
"gf-form-label query-keyword width-5"
ng-if=
"$index===0"
>
WHEN
</span>
</div>
<div
class=
"gf-form"
>
...
...
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