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
0d9378d1
Unverified
Commit
0d9378d1
authored
Dec 19, 2017
by
Carl Bergquist
Committed by
GitHub
Dec 19, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #10274 from bergquist/alerting_without_rows
Alerting without dashboard rows
parents
e1a527a8
644c2f7f
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
562 additions
and
66 deletions
+562
-66
pkg/services/alerting/extractor.go
+91
-66
pkg/services/alerting/extractor_test.go
+0
-0
pkg/services/alerting/test-data/graphite-alert.json
+64
-0
pkg/services/alerting/test-data/influxdb-alert.json
+283
-0
pkg/services/alerting/test-data/panels-missing-id.json
+63
-0
pkg/services/alerting/test-data/v5-dashboard.json
+61
-0
No files found.
pkg/services/alerting/extractor.go
View file @
0d9378d1
...
...
@@ -69,95 +69,120 @@ func copyJson(in *simplejson.Json) (*simplejson.Json, error) {
return
simplejson
.
NewJson
(
rawJson
)
}
func
(
e
*
DashAlertExtractor
)
GetAlert
s
(
)
([]
*
m
.
Alert
,
error
)
{
e
.
log
.
Debug
(
"GetAlerts"
)
func
(
e
*
DashAlertExtractor
)
GetAlert
FromPanels
(
jsonWithPanels
*
simplejson
.
Json
)
([]
*
m
.
Alert
,
error
)
{
alerts
:=
make
([]
*
m
.
Alert
,
0
)
dashboardJson
,
err
:=
copyJson
(
e
.
Dash
.
Data
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
panelObj
:=
range
jsonWithPanels
.
Get
(
"panels"
)
.
MustArray
()
{
panel
:=
simplejson
.
NewFromAny
(
panelObj
)
jsonAlert
,
hasAlert
:=
panel
.
CheckGet
(
"alert"
)
alerts
:=
make
([]
*
m
.
Alert
,
0
)
for
_
,
rowObj
:=
range
dashboardJson
.
Get
(
"rows"
)
.
MustArray
()
{
row
:=
simplejson
.
NewFromAny
(
rowObj
)
if
!
hasAlert
{
continue
}
for
_
,
panelObj
:=
range
row
.
Get
(
"panels"
)
.
MustArray
()
{
panel
:=
simplejson
.
NewFromAny
(
panelObj
)
jsonAlert
,
hasAlert
:=
panel
.
CheckGet
(
"alert"
)
panelId
,
err
:=
panel
.
Get
(
"id"
)
.
Int64
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"panel id is required. err %v"
,
err
)
}
if
!
hasAlert
{
continue
}
// backward compatibility check, can be removed later
enabled
,
hasEnabled
:=
jsonAlert
.
CheckGet
(
"enabled"
)
if
hasEnabled
&&
enabled
.
MustBool
()
==
false
{
continue
}
panelId
,
err
:=
panel
.
Get
(
"id"
)
.
Int64
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"panel id is required. err %v"
,
err
)
}
frequency
,
err
:=
getTimeDurationStringToSeconds
(
jsonAlert
.
Get
(
"frequency"
)
.
MustString
())
if
err
!=
nil
{
return
nil
,
ValidationError
{
Reason
:
"Could not parse frequency"
}
}
alert
:=
&
m
.
Alert
{
DashboardId
:
e
.
Dash
.
Id
,
OrgId
:
e
.
OrgId
,
PanelId
:
panelId
,
Id
:
jsonAlert
.
Get
(
"id"
)
.
MustInt64
(),
Name
:
jsonAlert
.
Get
(
"name"
)
.
MustString
(),
Handler
:
jsonAlert
.
Get
(
"handler"
)
.
MustInt64
(),
Message
:
jsonAlert
.
Get
(
"message"
)
.
MustString
(),
Frequency
:
frequency
,
}
for
_
,
condition
:=
range
jsonAlert
.
Get
(
"conditions"
)
.
MustArray
()
{
jsonCondition
:=
simplejson
.
NewFromAny
(
condition
)
jsonQuery
:=
jsonCondition
.
Get
(
"query"
)
queryRefId
:=
jsonQuery
.
Get
(
"params"
)
.
MustArray
()[
0
]
.
(
string
)
panelQuery
:=
findPanelQueryByRefId
(
panel
,
queryRefId
)
// backward compatibility check, can be removed later
enabled
,
hasEnabled
:=
jsonAlert
.
CheckGet
(
"enabled"
)
if
hasEnabled
&&
enabled
.
MustBool
()
==
false
{
continue
if
panelQuery
==
nil
{
reason
:=
fmt
.
Sprintf
(
"Alert on PanelId: %v refers to query(%s) that cannot be found"
,
alert
.
PanelId
,
queryRefId
)
return
nil
,
ValidationError
{
Reason
:
reason
}
}
frequency
,
err
:=
getTimeDurationStringToSeconds
(
jsonAlert
.
Get
(
"frequency"
)
.
MustString
())
if
err
!=
nil
{
return
nil
,
ValidationError
{
Reason
:
"Could not parse frequency"
}
dsName
:=
""
if
panelQuery
.
Get
(
"datasource"
)
.
MustString
()
!=
""
{
dsName
=
panelQuery
.
Get
(
"datasource"
)
.
MustString
()
}
else
if
panel
.
Get
(
"datasource"
)
.
MustString
()
!=
""
{
dsName
=
panel
.
Get
(
"datasource"
)
.
MustString
()
}
alert
:=
&
m
.
Alert
{
DashboardId
:
e
.
Dash
.
Id
,
OrgId
:
e
.
OrgId
,
PanelId
:
panelId
,
Id
:
jsonAlert
.
Get
(
"id"
)
.
MustInt64
(),
Name
:
jsonAlert
.
Get
(
"name"
)
.
MustString
(),
Handler
:
jsonAlert
.
Get
(
"handler"
)
.
MustInt64
(),
Message
:
jsonAlert
.
Get
(
"message"
)
.
MustString
(),
Frequency
:
frequency
,
if
datasource
,
err
:=
e
.
lookupDatasourceId
(
dsName
);
err
!=
nil
{
return
nil
,
err
}
else
{
jsonQuery
.
SetPath
([]
string
{
"datasourceId"
},
datasource
.
Id
)
}
for
_
,
condition
:=
range
jsonAlert
.
Get
(
"conditions"
)
.
MustArray
()
{
jsonCondition
:=
simplejson
.
NewFromAny
(
condition
)
if
interval
,
err
:=
panel
.
Get
(
"interval"
)
.
String
();
err
==
nil
{
panelQuery
.
Set
(
"interval"
,
interval
)
}
jsonQuery
:=
jsonCondition
.
Get
(
"query"
)
queryRefId
:=
jsonQuery
.
Get
(
"params"
)
.
MustArray
()[
0
]
.
(
string
)
panelQuery
:=
findPanelQueryByRefId
(
panel
,
queryRefId
)
jsonQuery
.
Set
(
"model"
,
panelQuery
.
Interface
())
}
if
panelQuery
==
nil
{
reason
:=
fmt
.
Sprintf
(
"Alert on PanelId: %v refers to query(%s) that cannot be found"
,
alert
.
PanelId
,
queryRefId
)
return
nil
,
ValidationError
{
Reason
:
reason
}
}
alert
.
Settings
=
jsonAlert
dsName
:=
""
if
panelQuery
.
Get
(
"datasource"
)
.
MustString
()
!=
""
{
dsName
=
panelQuery
.
Get
(
"datasource"
)
.
MustString
()
}
else
if
panel
.
Get
(
"datasource"
)
.
MustString
()
!=
""
{
dsName
=
panel
.
Get
(
"datasource"
)
.
MustString
()
}
// validate
_
,
err
=
NewRuleFromDBAlert
(
alert
)
if
err
==
nil
&&
alert
.
ValidToSave
()
{
alerts
=
append
(
alerts
,
alert
)
}
else
{
return
nil
,
err
}
}
if
datasource
,
err
:=
e
.
lookupDatasourceId
(
dsName
);
err
!=
nil
{
return
nil
,
err
}
else
{
jsonQuery
.
SetPath
([]
string
{
"datasourceId"
},
datasource
.
Id
)
}
return
alerts
,
nil
}
if
interval
,
err
:=
panel
.
Get
(
"interval"
)
.
String
();
err
==
nil
{
panelQuery
.
Set
(
"interval"
,
interval
)
}
func
(
e
*
DashAlertExtractor
)
GetAlerts
()
([]
*
m
.
Alert
,
error
)
{
e
.
log
.
Debug
(
"GetAlerts"
)
jsonQuery
.
Set
(
"model"
,
panelQuery
.
Interface
())
}
dashboardJson
,
err
:=
copyJson
(
e
.
Dash
.
Data
)
if
err
!=
nil
{
return
nil
,
err
}
alert
.
Settings
=
jsonAlert
alerts
:=
make
([]
*
m
.
Alert
,
0
)
// validate
_
,
err
=
NewRuleFromDBAlert
(
alert
)
if
err
==
nil
&&
alert
.
ValidToSave
()
{
alerts
=
append
(
alerts
,
alert
)
}
else
{
// We extract alerts from rows to be backwards compatible
// with the old dashboard json model.
rows
:=
dashboardJson
.
Get
(
"rows"
)
.
MustArray
()
if
len
(
rows
)
>
0
{
for
_
,
rowObj
:=
range
rows
{
row
:=
simplejson
.
NewFromAny
(
rowObj
)
a
,
err
:=
e
.
GetAlertFromPanels
(
row
)
if
err
!=
nil
{
return
nil
,
err
}
alerts
=
append
(
alerts
,
a
...
)
}
}
else
{
a
,
err
:=
e
.
GetAlertFromPanels
(
dashboardJson
)
if
err
!=
nil
{
return
nil
,
err
}
alerts
=
append
(
alerts
,
a
...
)
}
e
.
log
.
Debug
(
"Extracted alerts from dashboard"
,
"alertCount"
,
len
(
alerts
))
...
...
pkg/services/alerting/extractor_test.go
View file @
0d9378d1
This diff is collapsed.
Click to expand it.
pkg/services/alerting/test-data/graphite-alert.json
0 → 100644
View file @
0d9378d1
{
"id"
:
57
,
"title"
:
"Graphite 4"
,
"originalTitle"
:
"Graphite 4"
,
"tags"
:
[
"graphite"
],
"rows"
:
[
{
"panels"
:
[
{
"title"
:
"Active desktop users"
,
"editable"
:
true
,
"type"
:
"graph"
,
"id"
:
3
,
"targets"
:
[
{
"refId"
:
"A"
,
"target"
:
"aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"
}
],
"datasource"
:
null
,
"alert"
:
{
"name"
:
"name1"
,
"message"
:
"desc1"
,
"handler"
:
1
,
"frequency"
:
"60s"
,
"conditions"
:
[
{
"type"
:
"query"
,
"query"
:
{
"params"
:
[
"A"
,
"5m"
,
"now"
]},
"reducer"
:
{
"type"
:
"avg"
,
"params"
:
[]},
"evaluator"
:
{
"type"
:
">"
,
"params"
:
[
100
]}
}
]
}
},
{
"title"
:
"Active mobile users"
,
"id"
:
4
,
"targets"
:
[
{
"refId"
:
"A"
,
"target"
:
""
},
{
"refId"
:
"B"
,
"target"
:
"aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"
}
],
"datasource"
:
"graphite2"
,
"alert"
:
{
"name"
:
"name2"
,
"message"
:
"desc2"
,
"handler"
:
0
,
"frequency"
:
"60s"
,
"severity"
:
"warning"
,
"conditions"
:
[
{
"type"
:
"query"
,
"query"
:
{
"params"
:
[
"B"
,
"5m"
,
"now"
]},
"reducer"
:
{
"type"
:
"avg"
,
"params"
:
[]},
"evaluator"
:
{
"type"
:
">"
,
"params"
:
[
100
]}
}
]
}
}
]
}
]
}
\ No newline at end of file
pkg/services/alerting/test-data/influxdb-alert.json
0 → 100644
View file @
0d9378d1
{
"id"
:
4
,
"title"
:
"Influxdb"
,
"tags"
:
[
"apa"
],
"style"
:
"dark"
,
"timezone"
:
"browser"
,
"editable"
:
true
,
"hideControls"
:
false
,
"sharedCrosshair"
:
false
,
"rows"
:
[
{
"collapse"
:
false
,
"editable"
:
true
,
"height"
:
"450px"
,
"panels"
:
[
{
"alert"
:
{
"conditions"
:
[
{
"evaluator"
:
{
"params"
:
[
10
],
"type"
:
"gt"
},
"query"
:
{
"params"
:
[
"B"
,
"5m"
,
"now"
]
},
"reducer"
:
{
"params"
:
[],
"type"
:
"avg"
},
"type"
:
"query"
}
],
"frequency"
:
"3s"
,
"handler"
:
1
,
"name"
:
"Influxdb"
,
"noDataState"
:
"no_data"
,
"notifications"
:
[
{
"id"
:
6
}
]
},
"alerting"
:
{},
"aliasColors"
:
{
"logins.count.count"
:
"#890F02"
},
"bars"
:
false
,
"datasource"
:
"InfluxDB"
,
"editable"
:
true
,
"error"
:
false
,
"fill"
:
1
,
"grid"
:
{},
"id"
:
1
,
"interval"
:
">10s"
,
"isNew"
:
true
,
"legend"
:
{
"avg"
:
false
,
"current"
:
false
,
"max"
:
false
,
"min"
:
false
,
"show"
:
true
,
"total"
:
false
,
"values"
:
false
},
"lines"
:
true
,
"linewidth"
:
2
,
"links"
:
[],
"nullPointMode"
:
"connected"
,
"percentage"
:
false
,
"pointradius"
:
5
,
"points"
:
false
,
"renderer"
:
"flot"
,
"seriesOverrides"
:
[],
"span"
:
10
,
"stack"
:
false
,
"steppedLine"
:
false
,
"targets"
:
[
{
"groupBy"
:
[
{
"params"
:
[
"$interval"
],
"type"
:
"time"
},
{
"params"
:
[
"datacenter"
],
"type"
:
"tag"
},
{
"params"
:
[
"none"
],
"type"
:
"fill"
}
],
"hide"
:
false
,
"measurement"
:
"logins.count"
,
"policy"
:
"default"
,
"query"
:
"SELECT 8 * count(
\"
value
\"
) FROM
\"
logins.count
\"
WHERE $timeFilter GROUP BY time($interval),
\"
datacenter
\"
fill(none)"
,
"rawQuery"
:
true
,
"refId"
:
"B"
,
"resultFormat"
:
"time_series"
,
"select"
:
[
[
{
"params"
:
[
"value"
],
"type"
:
"field"
},
{
"params"
:
[],
"type"
:
"count"
}
]
],
"tags"
:
[]
},
{
"groupBy"
:
[
{
"params"
:
[
"$interval"
],
"type"
:
"time"
},
{
"params"
:
[
"null"
],
"type"
:
"fill"
}
],
"hide"
:
true
,
"measurement"
:
"cpu"
,
"policy"
:
"default"
,
"refId"
:
"A"
,
"resultFormat"
:
"time_series"
,
"select"
:
[
[
{
"params"
:
[
"value"
],
"type"
:
"field"
},
{
"params"
:
[],
"type"
:
"mean"
}
],
[
{
"params"
:
[
"value"
],
"type"
:
"field"
},
{
"params"
:
[],
"type"
:
"sum"
}
]
],
"tags"
:
[]
}
],
"thresholds"
:
[
{
"colorMode"
:
"critical"
,
"fill"
:
true
,
"line"
:
true
,
"op"
:
"gt"
,
"value"
:
10
}
],
"timeFrom"
:
null
,
"timeShift"
:
null
,
"title"
:
"Panel Title"
,
"tooltip"
:
{
"msResolution"
:
false
,
"ordering"
:
"alphabetical"
,
"shared"
:
true
,
"sort"
:
0
,
"value_type"
:
"cumulative"
},
"type"
:
"graph"
,
"xaxis"
:
{
"mode"
:
"time"
,
"name"
:
null
,
"show"
:
true
,
"values"
:
[]
},
"yaxes"
:
[
{
"format"
:
"short"
,
"logBase"
:
1
,
"max"
:
null
,
"min"
:
null
,
"show"
:
true
},
{
"format"
:
"short"
,
"logBase"
:
1
,
"max"
:
null
,
"min"
:
null
,
"show"
:
true
}
]
},
{
"editable"
:
true
,
"error"
:
false
,
"id"
:
2
,
"isNew"
:
true
,
"limit"
:
10
,
"links"
:
[],
"show"
:
"current"
,
"span"
:
2
,
"stateFilter"
:
[
"alerting"
],
"title"
:
"Alert status"
,
"type"
:
"alertlist"
}
],
"title"
:
"Row"
}
],
"time"
:
{
"from"
:
"now-5m"
,
"to"
:
"now"
},
"timepicker"
:
{
"now"
:
true
,
"refresh_intervals"
:
[
"5s"
,
"10s"
,
"30s"
,
"1m"
,
"5m"
,
"15m"
,
"30m"
,
"1h"
,
"2h"
,
"1d"
],
"time_options"
:
[
"5m"
,
"15m"
,
"1h"
,
"6h"
,
"12h"
,
"24h"
,
"2d"
,
"7d"
,
"30d"
]
},
"templating"
:
{
"list"
:
[]
},
"annotations"
:
{
"list"
:
[]
},
"schemaVersion"
:
13
,
"version"
:
120
,
"links"
:
[],
"gnetId"
:
null
}
\ No newline at end of file
pkg/services/alerting/test-data/panels-missing-id.json
0 → 100644
View file @
0d9378d1
{
"id"
:
57
,
"title"
:
"Graphite 4"
,
"originalTitle"
:
"Graphite 4"
,
"tags"
:
[
"graphite"
],
"rows"
:
[
{
"panels"
:
[
{
"title"
:
"Active desktop users"
,
"editable"
:
true
,
"type"
:
"graph"
,
"targets"
:
[
{
"refId"
:
"A"
,
"target"
:
"aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"
}
],
"datasource"
:
null
,
"alert"
:
{
"name"
:
"name1"
,
"message"
:
"desc1"
,
"handler"
:
1
,
"frequency"
:
"60s"
,
"conditions"
:
[
{
"type"
:
"query"
,
"query"
:
{
"params"
:
[
"A"
,
"5m"
,
"now"
]},
"reducer"
:
{
"type"
:
"avg"
,
"params"
:
[]},
"evaluator"
:
{
"type"
:
">"
,
"params"
:
[
100
]}
}
]
}
},
{
"title"
:
"Active mobile users"
,
"id"
:
4
,
"targets"
:
[
{
"refId"
:
"A"
,
"target"
:
""
},
{
"refId"
:
"B"
,
"target"
:
"aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"
}
],
"datasource"
:
"graphite2"
,
"alert"
:
{
"name"
:
"name2"
,
"message"
:
"desc2"
,
"handler"
:
0
,
"frequency"
:
"60s"
,
"severity"
:
"warning"
,
"conditions"
:
[
{
"type"
:
"query"
,
"query"
:
{
"params"
:
[
"B"
,
"5m"
,
"now"
]},
"reducer"
:
{
"type"
:
"avg"
,
"params"
:
[]},
"evaluator"
:
{
"type"
:
">"
,
"params"
:
[
100
]}
}
]
}
}
]
}
]
}
\ No newline at end of file
pkg/services/alerting/test-data/v5-dashboard.json
0 → 100644
View file @
0d9378d1
{
"id"
:
57
,
"title"
:
"Graphite 4"
,
"originalTitle"
:
"Graphite 4"
,
"tags"
:
[
"graphite"
],
"panels"
:
[
{
"title"
:
"Active desktop users"
,
"editable"
:
true
,
"type"
:
"graph"
,
"id"
:
3
,
"targets"
:
[
{
"refId"
:
"A"
,
"target"
:
"aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"
}
],
"datasource"
:
null
,
"alert"
:
{
"name"
:
"name1"
,
"message"
:
"desc1"
,
"handler"
:
1
,
"frequency"
:
"60s"
,
"conditions"
:
[
{
"type"
:
"query"
,
"query"
:
{
"params"
:
[
"A"
,
"5m"
,
"now"
]},
"reducer"
:
{
"type"
:
"avg"
,
"params"
:
[]},
"evaluator"
:
{
"type"
:
">"
,
"params"
:
[
100
]}
}
]
}
},
{
"title"
:
"Active mobile users"
,
"id"
:
4
,
"targets"
:
[
{
"refId"
:
"A"
,
"target"
:
""
},
{
"refId"
:
"B"
,
"target"
:
"aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"
}
],
"datasource"
:
"graphite2"
,
"alert"
:
{
"name"
:
"name2"
,
"message"
:
"desc2"
,
"handler"
:
0
,
"frequency"
:
"60s"
,
"severity"
:
"warning"
,
"conditions"
:
[
{
"type"
:
"query"
,
"query"
:
{
"params"
:
[
"B"
,
"5m"
,
"now"
]},
"reducer"
:
{
"type"
:
"avg"
,
"params"
:
[]},
"evaluator"
:
{
"type"
:
">"
,
"params"
:
[
100
]}
}
]
}
}
]
}
\ No newline at end of file
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