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
fdf051ad
Commit
fdf051ad
authored
Jun 09, 2016
by
bergquist
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(alerting): begin alert rule storage refactoring
parent
3898f427
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
300 additions
and
257 deletions
+300
-257
pkg/api/alerting.go
+0
-7
pkg/models/alerts.go
+25
-30
pkg/models/alerts_test.go
+39
-0
pkg/services/alerting/dashboard_parser.go
+75
-35
pkg/services/alerting/executor.go
+13
-14
pkg/services/alerting/executor_test.go
+8
-8
pkg/services/alerting/models.go
+31
-15
pkg/services/alerting/rule_reader.go
+3
-10
pkg/services/sqlstore/alert_rule.go
+1
-1
pkg/services/sqlstore/alert_rule_changes_test.go
+5
-14
pkg/services/sqlstore/alert_rule_test.go
+15
-45
pkg/services/sqlstore/alert_state_test.go
+5
-14
pkg/services/sqlstore/dashboard_parser_test.go
+76
-46
pkg/services/sqlstore/migrations/alert_mig.go
+1
-10
pkg/tsdb/graphite/graphite.go
+1
-7
public/app/plugins/panel/graph/alert_tab_ctrl.ts
+2
-1
No files found.
pkg/api/alerting.go
View file @
fdf051ad
...
...
@@ -64,15 +64,8 @@ func GetAlerts(c *middleware.Context) Response {
Id
:
alert
.
Id
,
DashboardId
:
alert
.
DashboardId
,
PanelId
:
alert
.
PanelId
,
Query
:
alert
.
Query
,
QueryRefId
:
alert
.
QueryRefId
,
WarnLevel
:
alert
.
WarnLevel
,
CritLevel
:
alert
.
CritLevel
,
Frequency
:
alert
.
Frequency
,
Name
:
alert
.
Name
,
Description
:
alert
.
Description
,
QueryRange
:
alert
.
QueryRange
,
Aggregator
:
alert
.
Aggregator
,
State
:
alert
.
State
,
})
}
...
...
pkg/models/alerts.go
View file @
fdf051ad
...
...
@@ -2,49 +2,44 @@ package models
import
(
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
)
type
AlertRule
struct
{
Id
int64
`json:"id"`
OrgId
int64
`json:"-"`
DatasourceId
int64
`json:"datasourceId"`
DashboardId
int64
`json:"dashboardId"`
PanelId
int64
`json:"panelId"`
Query
string
`json:"query"`
QueryRefId
string
`json:"queryRefId"`
WarnLevel
float64
`json:"warnLevel"`
CritLevel
float64
`json:"critLevel"`
WarnOperator
string
`json:"warnOperator"`
CritOperator
string
`json:"critOperator"`
Frequency
int64
`json:"frequency"`
Name
string
`json:"name"`
Description
string
`json:"description"`
QueryRange
int
`json:"queryRange"`
Aggregator
string
`json:"aggregator"`
State
string
`json:"state"`
Id
int64
OrgId
int64
DashboardId
int64
PanelId
int64
Name
string
Description
string
State
string
Created
time
.
Time
`json:"created"`
Updated
time
.
Time
`json:"updated"`
Created
time
.
Time
Updated
time
.
Time
Expression
*
simplejson
.
Json
}
func
(
alertRule
*
AlertRule
)
ValidToSave
()
bool
{
return
alertRule
.
Query
!=
""
&&
alertRule
.
Frequency
!=
0
&&
alertRule
.
QueryRange
!=
0
&&
alertRule
.
Name
!=
""
return
true
}
func
(
this
*
AlertRule
)
Equal
s
(
other
*
AlertRule
)
bool
{
func
(
this
*
AlertRule
)
ContainsUpdate
s
(
other
*
AlertRule
)
bool
{
result
:=
false
result
=
result
||
this
.
Aggregator
!=
other
.
Aggregator
result
=
result
||
this
.
CritLevel
!=
other
.
CritLevel
result
=
result
||
this
.
WarnLevel
!=
other
.
WarnLevel
result
=
result
||
this
.
WarnOperator
!=
other
.
WarnOperator
result
=
result
||
this
.
CritOperator
!=
other
.
CritOperator
result
=
result
||
this
.
Query
!=
other
.
Query
result
=
result
||
this
.
QueryRefId
!=
other
.
QueryRefId
result
=
result
||
this
.
Frequency
!=
other
.
Frequency
result
=
result
||
this
.
Name
!=
other
.
Name
result
=
result
||
this
.
Description
!=
other
.
Description
result
=
result
||
this
.
QueryRange
!=
other
.
QueryRange
json1
,
err1
:=
this
.
Expression
.
MarshalJSON
()
json2
,
err2
:=
other
.
Expression
.
MarshalJSON
()
if
err1
!=
nil
||
err2
!=
nil
{
return
false
}
result
=
result
||
string
(
json1
)
!=
string
(
json2
)
//don't compare .State! That would be insane.
return
result
...
...
pkg/models/alerts_test.go
0 → 100644
View file @
fdf051ad
package
models
import
(
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
.
"github.com/smartystreets/goconvey/convey"
)
func
TestAlertingModelTest
(
t
*
testing
.
T
)
{
Convey
(
"Testing Alerting model"
,
t
,
func
()
{
json1
,
_
:=
simplejson
.
NewJson
([]
byte
(
`{ "field": "value" }`
))
json2
,
_
:=
simplejson
.
NewJson
([]
byte
(
`{ "field": "value" }`
))
rule1
:=
&
AlertRule
{
Expression
:
json1
,
Name
:
"Namn"
,
Description
:
"Description"
,
}
rule2
:=
&
AlertRule
{
Expression
:
json2
,
Name
:
"Namn"
,
Description
:
"Description"
,
}
Convey
(
"Testing AlertRule equals"
,
func
()
{
So
(
rule1
.
ContainsUpdates
(
rule2
),
ShouldBeFalse
)
})
Convey
(
"Changing the expression should contain update"
,
func
()
{
json2
,
_
:=
simplejson
.
NewJson
([]
byte
(
`{ "field": "newValue" }`
))
rule1
.
Expression
=
json2
So
(
rule1
.
ContainsUpdates
(
rule2
),
ShouldBeTrue
)
})
})
}
pkg/services/alerting/dashboard_parser.go
View file @
fdf051ad
...
...
@@ -18,54 +18,63 @@ func ParseAlertsFromDashboard(cmd *m.SaveDashboardCommand) []*m.AlertRule {
alerting
:=
panel
.
Get
(
"alerting"
)
alert
:=
&
m
.
AlertRule
{
DashboardId
:
cmd
.
Result
.
Id
,
OrgId
:
cmd
.
Result
.
OrgId
,
PanelId
:
panel
.
Get
(
"id"
)
.
MustInt64
(),
Id
:
alerting
.
Get
(
"id"
)
.
MustInt64
(),
QueryRefId
:
alerting
.
Get
(
"queryRef"
)
.
MustString
(),
WarnLevel
:
alerting
.
Get
(
"warnLevel"
)
.
MustFloat64
(),
CritLevel
:
alerting
.
Get
(
"critLevel"
)
.
MustFloat64
(),
WarnOperator
:
alerting
.
Get
(
"warnOperator"
)
.
MustString
(),
CritOperator
:
alerting
.
Get
(
"critOperator"
)
.
MustString
(),
Frequency
:
alerting
.
Get
(
"frequency"
)
.
MustInt64
(),
Name
:
alerting
.
Get
(
"name"
)
.
MustString
(),
Description
:
alerting
.
Get
(
"description"
)
.
MustString
(),
QueryRange
:
alerting
.
Get
(
"queryRange"
)
.
MustInt
(),
Aggregator
:
alerting
.
Get
(
"aggregator"
)
.
MustString
(),
DashboardId
:
cmd
.
Result
.
Id
,
OrgId
:
cmd
.
Result
.
OrgId
,
PanelId
:
panel
.
Get
(
"id"
)
.
MustInt64
(),
Id
:
alerting
.
Get
(
"id"
)
.
MustInt64
(),
Name
:
alerting
.
Get
(
"name"
)
.
MustString
(),
Description
:
alerting
.
Get
(
"description"
)
.
MustString
(),
}
log
.
Info
(
"Alertrule: %v"
,
alert
.
Name
)
expression
:=
alerting
valueQuery
:=
expression
.
Get
(
"valueQuery"
)
valueQueryRef
:=
valueQuery
.
Get
(
"queryRefId"
)
.
MustString
()
for
_
,
targetsObj
:=
range
panel
.
Get
(
"targets"
)
.
MustArray
()
{
target
:=
simplejson
.
NewFromAny
(
targetsObj
)
if
target
.
Get
(
"refId"
)
.
MustString
()
==
alert
.
QueryRefId
{
targetJson
,
err
:=
target
.
MarshalJSON
()
if
err
==
nil
{
alert
.
Query
=
string
(
targetJson
)
if
target
.
Get
(
"refId"
)
.
MustString
()
==
valueQueryRef
{
datsourceName
:=
""
if
target
.
Get
(
"datasource"
)
.
MustString
()
!=
""
{
datsourceName
=
target
.
Get
(
"datasource"
)
.
MustString
()
}
else
if
panel
.
Get
(
"datasource"
)
.
MustString
()
!=
""
{
datsourceName
=
panel
.
Get
(
"datasource"
)
.
MustString
()
}
continue
}
}
if
panel
.
Get
(
"datasource"
)
.
MustString
()
==
""
{
query
:=
&
m
.
GetDataSourcesQuery
{
OrgId
:
cmd
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
query
);
err
==
nil
{
for
_
,
ds
:=
range
query
.
Result
{
if
ds
.
IsDefault
{
alert
.
DatasourceId
=
ds
.
Id
if
datsourceName
==
""
{
query
:=
&
m
.
GetDataSourcesQuery
{
OrgId
:
cmd
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
query
);
err
==
nil
{
for
_
,
ds
:=
range
query
.
Result
{
if
ds
.
IsDefault
{
valueQuery
.
Set
(
"datasourceId"
,
ds
.
Id
)
}
}
}
}
else
{
query
:=
&
m
.
GetDataSourceByNameQuery
{
Name
:
panel
.
Get
(
"datasource"
)
.
MustString
(),
OrgId
:
cmd
.
OrgId
,
}
bus
.
Dispatch
(
query
)
valueQuery
.
Set
(
"datasourceId"
,
query
.
Result
.
Id
)
}
targetQuery
:=
target
.
Get
(
"target"
)
.
MustString
()
if
targetQuery
!=
""
{
valueQuery
.
Set
(
"query"
,
targetQuery
)
}
}
}
else
{
query
:=
&
m
.
GetDataSourceByNameQuery
{
Name
:
panel
.
Get
(
"datasource"
)
.
MustString
(),
OrgId
:
cmd
.
OrgId
,
}
bus
.
Dispatch
(
query
)
alert
.
DatasourceId
=
query
.
Result
.
Id
}
if
alert
.
ValidToSave
()
{
expression
.
Set
(
"valueQuery"
,
valueQuery
)
alert
.
Expression
=
expression
alertRule
:=
&
AlertRule
{}
ParseAlertRulesFromAlertModel
(
alert
,
alertRule
)
if
alert
.
ValidToSave
()
&&
alertRule
.
IsValid
()
{
alerts
=
append
(
alerts
,
alert
)
}
}
...
...
@@ -73,3 +82,34 @@ func ParseAlertsFromDashboard(cmd *m.SaveDashboardCommand) []*m.AlertRule {
return
alerts
}
func
(
rule
*
AlertRule
)
IsValid
()
bool
{
return
rule
.
ValueQuery
.
Query
!=
""
}
func
ParseAlertRulesFromAlertModel
(
ruleDef
*
m
.
AlertRule
,
model
*
AlertRule
)
error
{
critical
:=
ruleDef
.
Expression
.
Get
(
"critical"
)
model
.
Critical
=
Level
{
Operator
:
critical
.
Get
(
"operator"
)
.
MustString
(),
Level
:
critical
.
Get
(
"level"
)
.
MustFloat64
(),
}
warning
:=
ruleDef
.
Expression
.
Get
(
"warning"
)
model
.
Warning
=
Level
{
Operator
:
warning
.
Get
(
"operator"
)
.
MustString
(),
Level
:
warning
.
Get
(
"level"
)
.
MustFloat64
(),
}
model
.
Frequency
=
ruleDef
.
Expression
.
Get
(
"frequency"
)
.
MustInt64
()
valueQuery
:=
ruleDef
.
Expression
.
Get
(
"valueQuery"
)
model
.
ValueQuery
=
AlertQuery
{
Query
:
valueQuery
.
Get
(
"query"
)
.
MustString
(),
DatasourceId
:
valueQuery
.
Get
(
"datasourceId"
)
.
MustInt64
(),
From
:
valueQuery
.
Get
(
"From"
)
.
MustInt64
(),
Until
:
valueQuery
.
Get
(
"until"
)
.
MustInt64
(),
Aggregator
:
valueQuery
.
Get
(
"aggregator"
)
.
MustString
(),
}
return
nil
}
pkg/services/alerting/executor.go
View file @
fdf051ad
...
...
@@ -102,12 +102,12 @@ func (e *ExecutorImpl) Execute(job *AlertJob, resultQueue chan *AlertResult) {
func
(
e
*
ExecutorImpl
)
executeQuery
(
job
*
AlertJob
)
(
tsdb
.
TimeSeriesSlice
,
error
)
{
getDsInfo
:=
&
m
.
GetDataSourceByIdQuery
{
Id
:
job
.
Rule
.
DatasourceId
,
Id
:
1
,
OrgId
:
job
.
Rule
.
OrgId
,
}
if
err
:=
bus
.
Dispatch
(
getDsInfo
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Could not find datasource
for %d"
,
job
.
Rule
.
DatasourceId
)
return
nil
,
fmt
.
Errorf
(
"Could not find datasource
"
)
}
req
:=
e
.
GetRequestForAlertRule
(
job
.
Rule
,
getDsInfo
.
Result
)
...
...
@@ -130,16 +130,15 @@ func (e *ExecutorImpl) executeQuery(job *AlertJob) (tsdb.TimeSeriesSlice, error)
}
func
(
e
*
ExecutorImpl
)
GetRequestForAlertRule
(
rule
*
AlertRule
,
datasource
*
m
.
DataSource
)
*
tsdb
.
Request
{
req
:=
&
tsdb
.
Request
{
TimeRange
:
tsdb
.
TimeRange
{
From
:
"-"
+
strconv
.
Itoa
(
rule
.
QueryRange
)
+
"s"
,
From
:
"-"
+
strconv
.
Itoa
(
int
(
rule
.
ValueQuery
.
From
)
)
+
"s"
,
To
:
"now"
,
},
Queries
:
[]
*
tsdb
.
Query
{
{
RefId
:
rule
.
QueryRefId
,
Query
:
rule
.
Query
,
RefId
:
"A"
,
Query
:
"apps.fakesite.*.counters.requests.count"
,
DataSource
:
&
tsdb
.
DataSourceInfo
{
Id
:
datasource
.
Id
,
Name
:
datasource
.
Name
,
...
...
@@ -159,15 +158,15 @@ func (e *ExecutorImpl) evaluateRule(rule *AlertRule, series tsdb.TimeSeriesSlice
for
_
,
serie
:=
range
series
{
log
.
Debug
(
"Evaluating series"
,
"series"
,
serie
.
Name
)
if
aggregator
[
rule
.
Aggregator
]
==
nil
{
if
aggregator
[
"avg"
]
==
nil
{
continue
}
var
aggValue
=
aggregator
[
rule
.
Aggregator
](
serie
)
var
critOperartor
=
operators
[
rule
.
CritOperator
]
var
critResult
=
critOperartor
(
aggValue
,
rule
.
CritLevel
)
var
aggValue
=
aggregator
[
"avg"
](
serie
)
var
critOperartor
=
operators
[
rule
.
Crit
ical
.
Operator
]
var
critResult
=
critOperartor
(
aggValue
,
rule
.
Crit
ical
.
Level
)
log
.
Trace
(
resultLogFmt
,
"Crit"
,
serie
.
Name
,
aggValue
,
rule
.
Crit
Operator
,
rule
.
Crit
Level
,
critResult
)
log
.
Trace
(
resultLogFmt
,
"Crit"
,
serie
.
Name
,
aggValue
,
rule
.
Crit
ical
.
Operator
,
rule
.
Critical
.
Level
,
critResult
)
if
critResult
{
return
&
AlertResult
{
State
:
alertstates
.
Critical
,
...
...
@@ -176,9 +175,9 @@ func (e *ExecutorImpl) evaluateRule(rule *AlertRule, series tsdb.TimeSeriesSlice
}
}
var
warnOperartor
=
operators
[
rule
.
Crit
Operator
]
var
warnResult
=
warnOperartor
(
aggValue
,
rule
.
Crit
Level
)
log
.
Trace
(
resultLogFmt
,
"Warn"
,
serie
.
Name
,
aggValue
,
rule
.
Warn
Operator
,
rule
.
Warn
Level
,
warnResult
)
var
warnOperartor
=
operators
[
rule
.
Warning
.
Operator
]
var
warnResult
=
warnOperartor
(
aggValue
,
rule
.
Warning
.
Level
)
log
.
Trace
(
resultLogFmt
,
"Warn"
,
serie
.
Name
,
aggValue
,
rule
.
Warn
ing
.
Operator
,
rule
.
Warning
.
Level
,
warnResult
)
if
warnResult
{
return
&
AlertResult
{
State
:
alertstates
.
Warn
,
...
...
pkg/services/alerting/executor_test.go
View file @
fdf051ad
...
...
@@ -14,7 +14,7 @@ func TestAlertingExecutor(t *testing.T) {
Convey
(
"single time serie"
,
func
()
{
Convey
(
"Show return ok since avg is above 2"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"sum"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
2
,
0
}}),
...
...
@@ -25,7 +25,7 @@ func TestAlertingExecutor(t *testing.T) {
})
Convey
(
"Show return critical since below 2"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
"<"
,
Aggregator
:
"sum"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
"<"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
2
,
0
}}),
...
...
@@ -36,7 +36,7 @@ func TestAlertingExecutor(t *testing.T) {
})
Convey
(
"Show return critical since sum is above 10"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"sum"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
9
,
0
},
{
9
,
0
}}),
...
...
@@ -47,7 +47,7 @@ func TestAlertingExecutor(t *testing.T) {
})
Convey
(
"Show return ok since avg is below 10"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"avg"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
9
,
0
},
{
9
,
0
}}),
...
...
@@ -58,7 +58,7 @@ func TestAlertingExecutor(t *testing.T) {
})
Convey
(
"Show return ok since min is below 10"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"min"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
11
,
0
},
{
9
,
0
}}),
...
...
@@ -69,7 +69,7 @@ func TestAlertingExecutor(t *testing.T) {
})
Convey
(
"Show return ok since max is above 10"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"max"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
1
,
0
},
{
11
,
0
}}),
...
...
@@ -82,7 +82,7 @@ func TestAlertingExecutor(t *testing.T) {
Convey
(
"muliple time series"
,
func
()
{
Convey
(
"both are ok"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"sum"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
2
,
0
}}),
...
...
@@ -94,7 +94,7 @@ func TestAlertingExecutor(t *testing.T) {
})
Convey
(
"first serie is good, second is critical"
,
func
()
{
rule
:=
&
AlertRule
{
Crit
Level
:
10
,
CritOperator
:
">"
,
Aggregator
:
"sum"
}
rule
:=
&
AlertRule
{
Crit
ical
:
Level
{
Level
:
10
,
Operator
:
">"
}
}
timeSeries
:=
[]
*
tsdb
.
TimeSeries
{
tsdb
.
NewTimeSeries
(
"test1"
,
[][
2
]
float64
{{
2
,
0
}}),
...
...
pkg/services/alerting/models.go
View file @
fdf051ad
...
...
@@ -18,21 +18,37 @@ type AlertResult struct {
}
type
AlertRule
struct
{
Id
int64
OrgId
int64
DatasourceId
int64
DashboardId
int64
PanelId
int64
Id
int64
OrgId
int64
DashboardId
int64
PanelId
int64
//WarnLevel float64
//CritLevel float64
//WarnOperator string
//CritOperator string
Frequency
int64
Name
string
Description
string
State
string
Warning
Level
Critical
Level
ValueQuery
AlertQuery
EvalFunc
string
EvalQuery
AlertQuery
EvalParam
string
}
type
Level
struct
{
Operator
string
Level
float64
}
type
AlertQuery
struct
{
Query
string
QueryRefId
string
WarnLevel
float64
CritLevel
float64
WarnOperator
string
CritOperator
string
Frequency
int64
Name
string
Description
string
QueryRange
int
DatasourceId
int64
Aggregator
string
State
string
From
int64
Until
int64
}
pkg/services/alerting/rule_reader.go
View file @
fdf051ad
...
...
@@ -52,19 +52,12 @@ func (arr *AlertRuleReader) Fetch() []*AlertRule {
model
:=
&
AlertRule
{}
model
.
Id
=
ruleDef
.
Id
model
.
OrgId
=
ruleDef
.
OrgId
model
.
DatasourceId
=
ruleDef
.
DatasourceId
model
.
Query
=
ruleDef
.
Query
model
.
QueryRefId
=
ruleDef
.
QueryRefId
model
.
WarnLevel
=
ruleDef
.
WarnLevel
model
.
WarnOperator
=
ruleDef
.
WarnOperator
model
.
CritLevel
=
ruleDef
.
CritLevel
model
.
CritOperator
=
ruleDef
.
CritOperator
model
.
Frequency
=
ruleDef
.
Frequency
model
.
Name
=
ruleDef
.
Name
model
.
Description
=
ruleDef
.
Description
model
.
Aggregator
=
ruleDef
.
Aggregator
model
.
State
=
ruleDef
.
State
model
.
QueryRange
=
ruleDef
.
QueryRange
ParseAlertRulesFromAlertModel
(
ruleDef
,
model
)
res
[
i
]
=
model
}
...
...
pkg/services/sqlstore/alert_rule.go
View file @
fdf051ad
...
...
@@ -186,7 +186,7 @@ func upsertAlerts(alerts []*m.AlertRule, posted []*m.AlertRule, sess *xorm.Sessi
}
if
update
{
if
alertToUpdate
.
Equal
s
(
alert
)
{
if
alertToUpdate
.
ContainsUpdate
s
(
alert
)
{
alert
.
Updated
=
time
.
Now
()
alert
.
State
=
alertToUpdate
.
State
_
,
err
:=
sess
.
Id
(
alert
.
Id
)
.
Update
(
alert
)
...
...
pkg/services/sqlstore/alert_rule_changes_test.go
View file @
fdf051ad
...
...
@@ -22,20 +22,11 @@ func TestAlertRuleChangesDataAccess(t *testing.T) {
Convey
(
"When dashboard is removed"
,
func
()
{
items
:=
[]
*
m
.
AlertRule
{
{
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
Query
:
"Query"
,
QueryRefId
:
"A"
,
WarnLevel
:
30
,
CritLevel
:
50
,
WarnOperator
:
">"
,
CritOperator
:
">"
,
Frequency
:
10
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
QueryRange
:
3600
,
Aggregator
:
"avg"
,
OrgId
:
FakeOrgId
,
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
OrgId
:
FakeOrgId
,
},
}
...
...
pkg/services/sqlstore/alert_rule_test.go
View file @
fdf051ad
...
...
@@ -8,7 +8,6 @@ import (
)
func
TestAlertingDataAccess
(
t
*
testing
.
T
)
{
Convey
(
"Testing Alerting data access"
,
t
,
func
()
{
InitTestDB
(
t
)
...
...
@@ -16,21 +15,11 @@ func TestAlertingDataAccess(t *testing.T) {
items
:=
[]
*
m
.
AlertRule
{
{
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
OrgId
:
testDash
.
OrgId
,
Query
:
"Query"
,
QueryRefId
:
"A"
,
WarnLevel
:
30
,
CritLevel
:
50
,
WarnOperator
:
">"
,
CritOperator
:
">"
,
Frequency
:
10
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
QueryRange
:
3600
,
Aggregator
:
"avg"
,
DatasourceId
:
42
,
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
OrgId
:
testDash
.
OrgId
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
},
}
...
...
@@ -58,25 +47,15 @@ func TestAlertingDataAccess(t *testing.T) {
alert
:=
alertQuery
.
Result
[
0
]
So
(
err2
,
ShouldBeNil
)
So
(
alert
.
Frequency
,
ShouldEqual
,
10
)
So
(
alert
.
WarnLevel
,
ShouldEqual
,
30
)
So
(
alert
.
CritLevel
,
ShouldEqual
,
50
)
So
(
alert
.
WarnOperator
,
ShouldEqual
,
">"
)
So
(
alert
.
CritOperator
,
ShouldEqual
,
">"
)
So
(
alert
.
Query
,
ShouldEqual
,
"Query"
)
So
(
alert
.
QueryRefId
,
ShouldEqual
,
"A"
)
So
(
alert
.
Name
,
ShouldEqual
,
"Alerting title"
)
So
(
alert
.
Description
,
ShouldEqual
,
"Alerting description"
)
So
(
alert
.
QueryRange
,
ShouldEqual
,
3600
)
So
(
alert
.
Aggregator
,
ShouldEqual
,
"avg"
)
So
(
alert
.
State
,
ShouldEqual
,
"OK"
)
So
(
alert
.
DatasourceId
,
ShouldEqual
,
42
)
})
Convey
(
"Alerts with same dashboard id and panel id should update"
,
func
()
{
modifiedItems
:=
items
modifiedItems
[
0
]
.
Query
=
"Updated Query
"
modifiedItems
[
0
]
.
State
=
"ALERT"
modifiedItems
[
0
]
.
Name
=
"New name
"
//
modifiedItems[0].State = "ALERT"
modifiedCmd
:=
m
.
SaveAlertsCommand
{
DashboardId
:
testDash
.
Id
,
...
...
@@ -97,7 +76,7 @@ func TestAlertingDataAccess(t *testing.T) {
So
(
err2
,
ShouldBeNil
)
So
(
len
(
query
.
Result
),
ShouldEqual
,
1
)
So
(
query
.
Result
[
0
]
.
Query
,
ShouldEqual
,
"Updated Query
"
)
So
(
query
.
Result
[
0
]
.
Name
,
ShouldEqual
,
"Name
"
)
Convey
(
"Alert state should not be updated"
,
func
()
{
So
(
query
.
Result
[
0
]
.
State
,
ShouldEqual
,
"OK"
)
...
...
@@ -120,19 +99,19 @@ func TestAlertingDataAccess(t *testing.T) {
{
DashboardId
:
testDash
.
Id
,
PanelId
:
1
,
Query
:
"1"
,
Name
:
"1"
,
OrgId
:
1
,
},
{
DashboardId
:
testDash
.
Id
,
PanelId
:
2
,
Query
:
"2"
,
Name
:
"2"
,
OrgId
:
1
,
},
{
DashboardId
:
testDash
.
Id
,
PanelId
:
3
,
Query
:
"3"
,
Name
:
"3"
,
OrgId
:
1
,
},
}
...
...
@@ -180,19 +159,10 @@ func TestAlertingDataAccess(t *testing.T) {
Convey
(
"When dashboard is removed"
,
func
()
{
items
:=
[]
*
m
.
AlertRule
{
{
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
Query
:
"Query"
,
QueryRefId
:
"A"
,
WarnLevel
:
30
,
CritLevel
:
50
,
WarnOperator
:
">"
,
CritOperator
:
">"
,
Frequency
:
10
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
QueryRange
:
3600
,
Aggregator
:
"avg"
,
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
},
}
...
...
pkg/services/sqlstore/alert_state_test.go
View file @
fdf051ad
...
...
@@ -15,20 +15,11 @@ func TestAlertingStateAccess(t *testing.T) {
items
:=
[]
*
m
.
AlertRule
{
{
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
OrgId
:
testDash
.
OrgId
,
Query
:
"Query"
,
QueryRefId
:
"A"
,
WarnLevel
:
30
,
CritLevel
:
50
,
WarnOperator
:
">"
,
CritOperator
:
">"
,
Frequency
:
10
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
QueryRange
:
3600
,
Aggregator
:
"avg"
,
PanelId
:
1
,
DashboardId
:
testDash
.
Id
,
OrgId
:
testDash
.
OrgId
,
Name
:
"Alerting title"
,
Description
:
"Alerting description"
,
},
}
...
...
pkg/services/sqlstore/dashboard_parser_test.go
View file @
fdf051ad
...
...
@@ -101,17 +101,45 @@ func TestAlertModel(t *testing.T) {
"timeShift": null,
"aliasColors": {},
"seriesOverrides": [],
"alerting": {
"queryRef": "A",
"warnLevel": 30,
"critLevel": 50,
"warnOperator": ">",
"critOperator": ">",
"aggregator": "sum",
"queryRange": 3600,
"frequency": 10,
"name": "active desktop users",
"description": "restart webservers"
"warning": {
"op": ">",
"level": 10
},
"critical": {
"op": ">",
"level": 20
},
"function": "static",
"valueQuery": {
"queryRefId": "A",
"from": "5m",
"to": "now",
"agg": "avg",
"params": [
"#A",
"5m",
"now",
"avg"
]
},
"evalQuery": {
"queryRefId": "A",
"from": "5m",
"to": "now",
"agg": "avg",
"params": [
"#A",
"5m",
"now",
"avg"
]
},
"evalStringParam1": "",
"name": "Alerting Panel Title alert"
},
"links": []
},
...
...
@@ -189,16 +217,42 @@ func TestAlertModel(t *testing.T) {
},
"seriesOverrides": [],
"alerting": {
"queryRef": "A",
"warnOperator": ">",
"critOperator": ">",
"warnLevel": 300,
"critLevel": 500,
"aggregator": "avg",
"queryRange": 3600,
"frequency": 10,
"name": "active mobile users",
"description": "restart itunes"
"warning": {
"op": ">",
"level": 10
},
"critical": {
"op": ">",
"level": 20
},
"function": "static",
"valueQuery": {
"queryRefId": "A",
"from": "5m",
"to": "now",
"agg": "avg",
"params": [
"#A",
"5m",
"now",
"avg"
]
},
"evalQuery": {
"queryRefId": "A",
"from": "5m",
"to": "now",
"agg": "avg",
"params": [
"#A",
"5m",
"now",
"avg"
]
},
"evalStringParam1": "",
"name": "Alerting Panel Title alert"
},
"links": []
}
...
...
@@ -379,37 +433,13 @@ func TestAlertModel(t *testing.T) {
So
(
v
.
DashboardId
,
ShouldEqual
,
1
)
So
(
v
.
PanelId
,
ShouldNotEqual
,
0
)
So
(
v
.
WarnLevel
,
ShouldNotBeEmpty
)
So
(
v
.
CritLevel
,
ShouldNotBeEmpty
)
So
(
v
.
Aggregator
,
ShouldNotBeEmpty
)
So
(
v
.
Query
,
ShouldNotBeEmpty
)
So
(
v
.
QueryRefId
,
ShouldNotBeEmpty
)
So
(
v
.
QueryRange
,
ShouldNotEqual
,
0
)
So
(
v
.
Frequency
,
ShouldNotEqual
,
0
)
So
(
v
.
Name
,
ShouldNotBeEmpty
)
So
(
v
.
Description
,
ShouldNotBeEmpty
)
}
So
(
alerts
[
0
]
.
WarnLevel
,
ShouldEqual
,
30
)
So
(
alerts
[
1
]
.
WarnLevel
,
ShouldEqual
,
300
)
So
(
alerts
[
0
]
.
Frequency
,
ShouldEqual
,
10
)
So
(
alerts
[
1
]
.
Frequency
,
ShouldEqual
,
10
)
So
(
alerts
[
0
]
.
CritLevel
,
ShouldEqual
,
50
)
So
(
alerts
[
1
]
.
CritLevel
,
ShouldEqual
,
500
)
So
(
alerts
[
0
]
.
CritOperator
,
ShouldEqual
,
">"
)
So
(
alerts
[
1
]
.
CritOperator
,
ShouldEqual
,
">"
)
So
(
alerts
[
0
]
.
WarnOperator
,
ShouldEqual
,
">"
)
So
(
alerts
[
1
]
.
WarnOperator
,
ShouldEqual
,
">"
)
So
(
alerts
[
0
]
.
Query
,
ShouldEqual
,
`{"refId":"A","target":"aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"}`
)
So
(
alerts
[
1
]
.
Query
,
ShouldEqual
,
`{"refId":"A","target":"aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`
)
So
(
alerts
[
0
]
.
DatasourceId
,
ShouldEqual
,
2
)
So
(
alerts
[
1
]
.
DatasourceId
,
ShouldEqual
,
1
)
expr
:=
simplejson
.
NewFromAny
(
v
.
Expression
)
So
(
expr
.
Get
(
"valueQuery"
)
.
Get
(
"query"
)
.
MustString
(),
ShouldNotEqual
,
""
)
So
(
expr
.
Get
(
"valueQuery"
)
.
Get
(
"datsourceId"
)
.
MustInt64
(),
ShouldNotEqual
,
0
)
}
})
})
}
pkg/services/sqlstore/migrations/alert_mig.go
View file @
fdf051ad
...
...
@@ -11,21 +11,12 @@ func addAlertMigrations(mg *Migrator) {
Columns
:
[]
*
Column
{
{
Name
:
"id"
,
Type
:
DB_BigInt
,
IsPrimaryKey
:
true
,
IsAutoIncrement
:
true
},
{
Name
:
"dashboard_id"
,
Type
:
DB_BigInt
,
Nullable
:
false
},
{
Name
:
"datasource_id"
,
Type
:
DB_BigInt
,
Nullable
:
false
},
{
Name
:
"panel_id"
,
Type
:
DB_BigInt
,
Nullable
:
false
},
{
Name
:
"org_id"
,
Type
:
DB_BigInt
,
Nullable
:
false
},
{
Name
:
"query"
,
Type
:
DB_Text
,
Nullable
:
false
},
{
Name
:
"query_ref_id"
,
Type
:
DB_NVarchar
,
Length
:
255
,
Nullable
:
false
},
{
Name
:
"warn_level"
,
Type
:
DB_Float
,
Nullable
:
false
},
{
Name
:
"warn_operator"
,
Type
:
DB_NVarchar
,
Length
:
10
,
Nullable
:
false
},
{
Name
:
"crit_level"
,
Type
:
DB_Float
,
Nullable
:
false
},
{
Name
:
"crit_operator"
,
Type
:
DB_NVarchar
,
Length
:
10
,
Nullable
:
false
},
{
Name
:
"frequency"
,
Type
:
DB_BigInt
,
Nullable
:
false
},
{
Name
:
"name"
,
Type
:
DB_NVarchar
,
Length
:
255
,
Nullable
:
false
},
{
Name
:
"description"
,
Type
:
DB_NVarchar
,
Length
:
255
,
Nullable
:
false
},
{
Name
:
"query_range"
,
Type
:
DB_Int
,
Nullable
:
false
},
{
Name
:
"aggregator"
,
Type
:
DB_NVarchar
,
Length
:
255
,
Nullable
:
false
},
{
Name
:
"state"
,
Type
:
DB_NVarchar
,
Length
:
255
,
Nullable
:
false
},
{
Name
:
"expression"
,
Type
:
DB_Text
,
Nullable
:
false
},
{
Name
:
"created"
,
Type
:
DB_DateTime
,
Nullable
:
false
},
{
Name
:
"updated"
,
Type
:
DB_DateTime
,
Nullable
:
false
},
},
...
...
pkg/tsdb/graphite/graphite.go
View file @
fdf051ad
...
...
@@ -7,7 +7,6 @@ import (
"net/url"
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/tsdb"
)
...
...
@@ -39,7 +38,7 @@ func (e *GraphiteExecutor) Execute(queries tsdb.QuerySlice, context *tsdb.QueryC
for
_
,
query
:=
range
queries
{
params
[
"target"
]
=
[]
string
{
getTargetFromQuery
(
query
.
Query
)
,
query
.
Query
,
}
}
...
...
@@ -77,8 +76,3 @@ func (e *GraphiteExecutor) Execute(queries tsdb.QuerySlice, context *tsdb.QueryC
result
.
QueryResults
[
"A"
]
=
queryRes
return
result
}
func
getTargetFromQuery
(
query
string
)
string
{
json
,
_
:=
simplejson
.
NewJson
([]
byte
(
query
))
return
json
.
Get
(
"target"
)
.
MustString
()
}
public/app/plugins/panel/graph/alert_tab_ctrl.ts
View file @
fdf051ad
...
...
@@ -81,6 +81,7 @@ export class AlertTabCtrl {
var
defaultName
=
(
this
.
panelCtrl
.
dashboard
.
title
+
' '
+
this
.
panel
.
title
+
' alert'
);
this
.
panel
.
alerting
.
name
=
this
.
panel
.
alerting
.
name
||
defaultName
;
this
.
panel
.
alerting
.
description
=
this
.
panel
.
alerting
.
description
||
defaultName
;
this
.
panel
.
targets
.
map
(
target
=>
{
this
.
metricTargets
.
push
(
target
);
...
...
@@ -92,7 +93,7 @@ export class AlertTabCtrl {
}
evalFuncChanged
()
{
var
evalFuncDef
=
_
.
findWhere
(
this
.
evalFuncs
,
{
value
:
this
.
rule
.
e
xpression
.
e
valFunc
});
var
evalFuncDef
=
_
.
findWhere
(
this
.
evalFuncs
,
{
value
:
this
.
rule
.
evalFunc
});
console
.
log
(
evalFuncDef
);
this
.
secondParam
=
evalFuncDef
.
secondParam
;
}
...
...
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