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
bef216b6
Commit
bef216b6
authored
Feb 24, 2017
by
Carl Bergquist
Committed by
GitHub
Feb 24, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7526 from Mic92/master
Add Pushover alert notifications
parents
67b8b974
f069aae5
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
238 additions
and
0 deletions
+238
-0
pkg/metrics/metrics.go
+2
-0
pkg/services/alerting/notifiers/pushover.go
+177
-0
pkg/services/alerting/notifiers/pushover_test.go
+58
-0
public/app/features/alerting/alert_tab_ctrl.ts
+1
-0
No files found.
pkg/metrics/metrics.go
View file @
bef216b6
...
...
@@ -50,6 +50,7 @@ var (
M_Alerting_Notification_Sent_OpsGenie
Counter
M_Alerting_Notification_Sent_Telegram
Counter
M_Alerting_Notification_Sent_Sensu
Counter
M_Alerting_Notification_Sent_Pushover
Counter
M_Aws_CloudWatch_GetMetricStatistics
Counter
M_Aws_CloudWatch_ListMetrics
Counter
...
...
@@ -120,6 +121,7 @@ func initMetricVars(settings *MetricSettings) {
M_Alerting_Notification_Sent_Telegram
=
RegCounter
(
"alerting.notifications_sent"
,
"type"
,
"telegram"
)
M_Alerting_Notification_Sent_Sensu
=
RegCounter
(
"alerting.notifications_sent"
,
"type"
,
"sensu"
)
M_Alerting_Notification_Sent_LINE
=
RegCounter
(
"alerting.notifications_sent"
,
"type"
,
"LINE"
)
M_Alerting_Notification_Sent_Pushover
=
RegCounter
(
"alerting.notifications_sent"
,
"type"
,
"pushover"
)
M_Aws_CloudWatch_GetMetricStatistics
=
RegCounter
(
"aws.cloudwatch.get_metric_statistics"
)
M_Aws_CloudWatch_ListMetrics
=
RegCounter
(
"aws.cloudwatch.list_metrics"
)
...
...
pkg/services/alerting/notifiers/pushover.go
0 → 100644
View file @
bef216b6
package
notifiers
import
(
"fmt"
"net/url"
"strconv"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/metrics"
m
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
)
const
PUSHOVER_ENDPOINT
=
"https://api.pushover.net/1/messages.json"
func
init
()
{
alerting
.
RegisterNotifier
(
&
alerting
.
NotifierPlugin
{
Type
:
"pushover"
,
Name
:
"Pushover"
,
Description
:
"Sends HTTP POST request to the Pushover API"
,
Factory
:
NewPushoverNotifier
,
OptionsTemplate
:
`
<h3 class="page-heading">Pushover settings</h3>
<div class="gf-form">
<span class="gf-form-label width-10">API Token</span>
<input type="text" class="gf-form-input" required placeholder="Application token" ng-model="ctrl.model.settings.apiToken"></input>
</div>
<div class="gf-form">
<span class="gf-form-label width-10">User key(s)</span>
<input type="text" class="gf-form-input" required placeholder="comma-separated list" ng-model="ctrl.model.settings.userKey"></input>
</div>
<div class="gf-form">
<span class="gf-form-label width-10">Device(s) (optional)</span>
<input type="text" class="gf-form-input" placeholder="comma-separated list; leave empty to send to all devices" ng-model="ctrl.model.settings.device"></input>
</div>
<div class="gf-form">
<span class="gf-form-label width-10">Priority</span>
<select class="gf-form-input max-width-14" ng-model="ctrl.model.settings.priority" ng-options="v as k for (k, v) in {
Emergency: '2',
High: '1',
Normal: '0',
Low: '-1',
Lowest: '-2'
}" ng-init="ctrl.model.settings.priority=ctrl.model.settings.priority||'0'"></select>
</div>
<div class="gf-form" ng-show="ctrl.model.settings.priority == '2'">
<span class="gf-form-label width-10">Retry</span>
<input type="text" class="gf-form-input max-width-14" ng-required="ctrl.model.settings.priority == '2'" placeholder="minimum 30 seconds" ng-model="ctrl.model.settings.retry" ng-init="ctrl.model.settings.retry=ctrl.model.settings.retry||'60'></input>
</div>
<div class="gf-form" ng-show="ctrl.model.settings.priority == '2'">
<span class="gf-form-label width-10">Expire</span>
<input type="text" class="gf-form-input max-width-14" ng-required="ctrl.model.settings.priority == '2'" placeholder="maximum 86400 seconds" ng-model="ctrl.model.settings.expire" ng-init="ctrl.model.settings.expire=ctrl.model.settings.expire||'3600'"></input>
</div>
<div class="gf-form">
<span class="gf-form-label width-10">Sound</span>
<select class="gf-form-input max-width-14" ng-model="ctrl.model.settings.sound" ng-options="s for s in [
'default',
'pushover',
'bike',
'bugle',
'cashregister',
'classical',
'cosmic',
'falling',
'gamelan',
'incoming',
'intermission',
'magic',
'mechanical',
'pianobar',
'siren',
'spacealarm',
'tugboat',
'alien',
'climb',
'persistent',
'echo',
'updown',
'none'
]" ng-init="ctrl.model.settings.sound=ctrl.model.settings.sound||'default'"></select>
</div>
`
,
})
}
func
NewPushoverNotifier
(
model
*
m
.
AlertNotification
)
(
alerting
.
Notifier
,
error
)
{
userKey
:=
model
.
Settings
.
Get
(
"userKey"
)
.
MustString
()
apiToken
:=
model
.
Settings
.
Get
(
"apiToken"
)
.
MustString
()
device
:=
model
.
Settings
.
Get
(
"device"
)
.
MustString
()
priority
,
_
:=
strconv
.
Atoi
(
model
.
Settings
.
Get
(
"priority"
)
.
MustString
())
retry
,
_
:=
strconv
.
Atoi
(
model
.
Settings
.
Get
(
"retry"
)
.
MustString
())
expire
,
_
:=
strconv
.
Atoi
(
model
.
Settings
.
Get
(
"expire"
)
.
MustString
())
sound
:=
model
.
Settings
.
Get
(
"sound"
)
.
MustString
()
if
userKey
==
""
{
return
nil
,
alerting
.
ValidationError
{
Reason
:
"User key not given"
}
}
if
apiToken
==
""
{
return
nil
,
alerting
.
ValidationError
{
Reason
:
"API token not given"
}
}
return
&
PushoverNotifier
{
NotifierBase
:
NewNotifierBase
(
model
.
Id
,
model
.
IsDefault
,
model
.
Name
,
model
.
Type
,
model
.
Settings
),
UserKey
:
userKey
,
ApiToken
:
apiToken
,
Priority
:
priority
,
Retry
:
retry
,
Expire
:
expire
,
Device
:
device
,
Sound
:
sound
,
log
:
log
.
New
(
"alerting.notifier.pushover"
),
},
nil
}
type
PushoverNotifier
struct
{
NotifierBase
UserKey
string
ApiToken
string
Priority
int
Retry
int
Expire
int
Device
string
Sound
string
log
log
.
Logger
}
func
(
this
*
PushoverNotifier
)
Notify
(
evalContext
*
alerting
.
EvalContext
)
error
{
metrics
.
M_Alerting_Notification_Sent_Pushover
.
Inc
(
1
)
ruleUrl
,
err
:=
evalContext
.
GetRuleUrl
()
if
err
!=
nil
{
this
.
log
.
Error
(
"Failed get rule link"
,
"error"
,
err
)
return
err
}
message
:=
evalContext
.
Rule
.
Message
for
idx
,
evt
:=
range
evalContext
.
EvalMatches
{
message
+=
fmt
.
Sprintf
(
"
\n
<b>%s</b>: %v"
,
evt
.
Metric
,
evt
.
Value
)
if
idx
>
4
{
break
}
}
if
evalContext
.
Error
!=
nil
{
message
+=
fmt
.
Sprintf
(
"
\n
<b>Error message</b> %s"
,
evalContext
.
Error
.
Error
())
}
q
:=
url
.
Values
{}
q
.
Add
(
"user"
,
this
.
UserKey
)
q
.
Add
(
"token"
,
this
.
ApiToken
)
q
.
Add
(
"priority"
,
strconv
.
Itoa
(
this
.
Priority
))
if
this
.
Priority
==
2
{
q
.
Add
(
"retry"
,
strconv
.
Itoa
(
this
.
Retry
))
q
.
Add
(
"expire"
,
strconv
.
Itoa
(
this
.
Expire
))
}
if
this
.
Device
!=
""
{
q
.
Add
(
"device"
,
this
.
Device
)
}
if
this
.
Sound
!=
"default"
{
q
.
Add
(
"sound"
,
this
.
Sound
)
}
q
.
Add
(
"title"
,
evalContext
.
GetNotificationTitle
())
q
.
Add
(
"url"
,
ruleUrl
)
q
.
Add
(
"url_title"
,
"Show dashboard with alert"
)
q
.
Add
(
"message"
,
message
)
q
.
Add
(
"html"
,
"1"
)
cmd
:=
&
m
.
SendWebhookSync
{
Url
:
PUSHOVER_ENDPOINT
,
HttpMethod
:
"POST"
,
HttpHeader
:
map
[
string
]
string
{
"Content-Type"
:
"application/x-www-form-urlencoded"
},
Body
:
q
.
Encode
(),
}
if
err
:=
bus
.
DispatchCtx
(
evalContext
.
Ctx
,
cmd
);
err
!=
nil
{
this
.
log
.
Error
(
"Failed to send pushover notification"
,
"error"
,
err
,
"webhook"
,
this
.
Name
)
return
err
}
return
nil
}
pkg/services/alerting/notifiers/pushover_test.go
0 → 100644
View file @
bef216b6
package
notifiers
import
(
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
m
"github.com/grafana/grafana/pkg/models"
.
"github.com/smartystreets/goconvey/convey"
)
func
TestPushoverNotifier
(
t
*
testing
.
T
)
{
Convey
(
"Pushover notifier tests"
,
t
,
func
()
{
Convey
(
"Parsing alert notification from settings"
,
func
()
{
Convey
(
"empty settings should return error"
,
func
()
{
json
:=
`{ }`
settingsJSON
,
_
:=
simplejson
.
NewJson
([]
byte
(
json
))
model
:=
&
m
.
AlertNotification
{
Name
:
"Pushover"
,
Type
:
"pushover"
,
Settings
:
settingsJSON
,
}
_
,
err
:=
NewPushoverNotifier
(
model
)
So
(
err
,
ShouldNotBeNil
)
})
Convey
(
"from settings"
,
func
()
{
json
:=
`
{
"apiToken": "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve",
"userKey": "tzNZYf36y0ohWwXo4XoUrB61rz1A4o",
"priority": "1",
"sound": "pushover"
}`
settingsJSON
,
_
:=
simplejson
.
NewJson
([]
byte
(
json
))
model
:=
&
m
.
AlertNotification
{
Name
:
"Pushover"
,
Type
:
"pushover"
,
Settings
:
settingsJSON
,
}
not
,
err
:=
NewPushoverNotifier
(
model
)
pushoverNotifier
:=
not
.
(
*
PushoverNotifier
)
So
(
err
,
ShouldBeNil
)
So
(
pushoverNotifier
.
Name
,
ShouldEqual
,
"Pushover"
)
So
(
pushoverNotifier
.
Type
,
ShouldEqual
,
"pushover"
)
So
(
pushoverNotifier
.
ApiToken
,
ShouldEqual
,
"4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve"
)
So
(
pushoverNotifier
.
UserKey
,
ShouldEqual
,
"tzNZYf36y0ohWwXo4XoUrB61rz1A4o"
)
So
(
pushoverNotifier
.
Priority
,
ShouldEqual
,
1
)
So
(
pushoverNotifier
.
Sound
,
ShouldEqual
,
"pushover"
)
})
})
})
}
public/app/features/alerting/alert_tab_ctrl.ts
View file @
bef216b6
...
...
@@ -105,6 +105,7 @@ export class AlertTabCtrl {
case
"pagerduty"
:
return
"fa fa-bullhorn"
;
case
"opsgenie"
:
return
"fa fa-bell"
;
case
"hipchat"
:
return
"fa fa-mail-forward"
;
case
"pushover"
:
return
"fa fa-mobile"
;
}
}
...
...
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