mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Customise OK notification priorities for Pushover notifier (#30169)
* pushover: Customise OK notification priorities * Apply suggestions from code review * Fix build failure Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/alerting/notifiers/pushover.go Co-authored-by: Sofia Papagiannaki <papagian@users.noreply.github.com> * Update docs * Apply suggestions from code review Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Sofia Papagiannaki <papagian@users.noreply.github.com> Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
This commit is contained in:
parent
141202f518
commit
4ed283e7bf
@ -421,13 +421,17 @@ The following sections detail the supported settings and secure settings for eac
|
|||||||
|
|
||||||
#### Alert notification `pushover`
|
#### Alert notification `pushover`
|
||||||
|
|
||||||
| Name | Secure setting |
|
| Name | Secure setting |
|
||||||
| -------- | -------------- |
|
| -------- | -------------- |
|
||||||
| apiToken | yes |
|
| apiToken | yes |
|
||||||
| userKey | yes |
|
| userKey | yes |
|
||||||
| device | |
|
| device | |
|
||||||
| retry | |
|
| priority | |
|
||||||
| expire | |
|
| okPriority | |
|
||||||
|
| retry | |
|
||||||
|
| expire | |
|
||||||
|
| sound | |
|
||||||
|
| okSound | |
|
||||||
|
|
||||||
#### Alert notification `slack`
|
#### Alert notification `slack`
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ Microsoft Teams | `teams` | yes, external only | no
|
|||||||
OpsGenie | `opsgenie` | yes, external only | yes
|
OpsGenie | `opsgenie` | yes, external only | yes
|
||||||
[Pagerduty](#pagerduty) | `pagerduty` | yes, external only | yes
|
[Pagerduty](#pagerduty) | `pagerduty` | yes, external only | yes
|
||||||
Prometheus Alertmanager | `prometheus-alertmanager` | yes, external only | yes
|
Prometheus Alertmanager | `prometheus-alertmanager` | yes, external only | yes
|
||||||
Pushover | `pushover` | yes | no
|
[Pushover](#pushover) | `pushover` | yes | no
|
||||||
Sensu | `sensu` | yes, external only | no
|
Sensu | `sensu` | yes, external only | no
|
||||||
[Sensu Go](#sensu-go) | `sensugo` | yes, external only | no
|
[Sensu Go](#sensu-go) | `sensugo` | yes, external only | no
|
||||||
[Slack](#slack) | `slack` | yes | no
|
[Slack](#slack) | `slack` | yes | no
|
||||||
@ -130,6 +130,24 @@ Move any existing rules using `custom_details.myMetric` to `custom_details.queri
|
|||||||
This behavior will become the default in a future version of Grafana.
|
This behavior will become the default in a future version of Grafana.
|
||||||
|
|
||||||
> Using `dedup_key` tag will override Grafana generated `dedup_key` with a custom key.
|
> Using `dedup_key` tag will override Grafana generated `dedup_key` with a custom key.
|
||||||
|
|
||||||
|
### Pushover
|
||||||
|
|
||||||
|
To set up Pushover, you must provide a user key and an API token. Refer to [What is Pushover and how do I use it](https://support.pushover.net/i7-what-is-pushover-and-how-do-i-use-it) for instructions on how to generate them.
|
||||||
|
|
||||||
|
|
||||||
|
Setting | Description
|
||||||
|
---------- | -----------
|
||||||
|
API Token | Application token
|
||||||
|
User key(s) | A comma-separated list of user keys
|
||||||
|
Device(s) | A comma-separated list of devices
|
||||||
|
Priority | The priority alerting nottifications are sent
|
||||||
|
OK priority | The priority OK notifications are sent; if not set, then OK notifications are sent with the priority set for alerting notifications
|
||||||
|
Retry | How often (in seconds) the Pushover servers send the same notification to the user. (minimum 30 seconds)
|
||||||
|
Expire | How many seconds your notification will continue to be retried for (maximum 86400 seconds)
|
||||||
|
Alerting sound | The sound for alerting notifications
|
||||||
|
OK sound | The sound for OK notifications
|
||||||
|
|
||||||
### Webhook
|
### Webhook
|
||||||
|
|
||||||
The webhook notification is a simple way to send information about a state change over HTTP to a custom endpoint.
|
The webhook notification is a simple way to send information about a state change over HTTP to a custom endpoint.
|
||||||
|
@ -91,6 +91,29 @@ func init() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priorityOptions := []alerting.SelectOption{
|
||||||
|
{
|
||||||
|
Value: "2",
|
||||||
|
Label: "Emergency",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "1",
|
||||||
|
Label: "High",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "0",
|
||||||
|
Label: "Normal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "-1",
|
||||||
|
Label: "Low",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "-2",
|
||||||
|
Label: "Lowest",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
alerting.RegisterNotifier(&alerting.NotifierPlugin{
|
alerting.RegisterNotifier(&alerting.NotifierPlugin{
|
||||||
Type: "pushover",
|
Type: "pushover",
|
||||||
Name: "Pushover",
|
Name: "Pushover",
|
||||||
@ -124,53 +147,32 @@ func init() {
|
|||||||
PropertyName: "device",
|
PropertyName: "device",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: "Priority",
|
Label: "Alerting priority",
|
||||||
Element: alerting.ElementTypeSelect,
|
Element: alerting.ElementTypeSelect,
|
||||||
SelectOptions: []alerting.SelectOption{
|
SelectOptions: priorityOptions,
|
||||||
{
|
PropertyName: "priority",
|
||||||
Value: "2",
|
|
||||||
Label: "Emergency",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "1",
|
|
||||||
Label: "High",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "0",
|
|
||||||
Label: "Normal",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "-1",
|
|
||||||
Label: "Low",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "-2",
|
|
||||||
Label: "Lowest",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
PropertyName: "priority",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: "Retry",
|
Label: "OK priority",
|
||||||
|
Element: alerting.ElementTypeSelect,
|
||||||
|
SelectOptions: priorityOptions,
|
||||||
|
PropertyName: "okPriority",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Description: "How often (in seconds) the Pushover servers will send the same alerting or OK notification to the user.",
|
||||||
|
Label: "Retry (Only used for Emergency Priority)",
|
||||||
Element: alerting.ElementTypeInput,
|
Element: alerting.ElementTypeInput,
|
||||||
InputType: alerting.InputTypeText,
|
InputType: alerting.InputTypeText,
|
||||||
Placeholder: "minimum 30 seconds",
|
Placeholder: "minimum 30 seconds",
|
||||||
PropertyName: "retry",
|
PropertyName: "retry",
|
||||||
ShowWhen: alerting.ShowWhen{
|
|
||||||
Field: "priority",
|
|
||||||
Is: "2",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: "Expire",
|
Description: "How many seconds the alerting or OK notification will continue to be retried.",
|
||||||
|
Label: "Expire (Only used for Emergency Priority)",
|
||||||
Element: alerting.ElementTypeInput,
|
Element: alerting.ElementTypeInput,
|
||||||
InputType: alerting.InputTypeText,
|
InputType: alerting.InputTypeText,
|
||||||
Placeholder: "maximum 86400 seconds",
|
Placeholder: "maximum 86400 seconds",
|
||||||
PropertyName: "expire",
|
PropertyName: "expire",
|
||||||
ShowWhen: alerting.ShowWhen{
|
|
||||||
Field: "priority",
|
|
||||||
Is: "2",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: "Alerting sound",
|
Label: "Alerting sound",
|
||||||
@ -193,7 +195,14 @@ func NewPushoverNotifier(model *models.AlertNotification) (alerting.Notifier, er
|
|||||||
userKey := model.DecryptedValue("userKey", model.Settings.Get("userKey").MustString())
|
userKey := model.DecryptedValue("userKey", model.Settings.Get("userKey").MustString())
|
||||||
APIToken := model.DecryptedValue("apiToken", model.Settings.Get("apiToken").MustString())
|
APIToken := model.DecryptedValue("apiToken", model.Settings.Get("apiToken").MustString())
|
||||||
device := model.Settings.Get("device").MustString()
|
device := model.Settings.Get("device").MustString()
|
||||||
priority, _ := strconv.Atoi(model.Settings.Get("priority").MustString())
|
alertingPriority, err := strconv.Atoi(model.Settings.Get("priority").MustString("0")) // default Normal
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert alerting priority to integer: %w", err)
|
||||||
|
}
|
||||||
|
okPriority, err := strconv.Atoi(model.Settings.Get("okPriority").MustString("0")) // default Normal
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert OK priority to integer: %w", err)
|
||||||
|
}
|
||||||
retry, _ := strconv.Atoi(model.Settings.Get("retry").MustString())
|
retry, _ := strconv.Atoi(model.Settings.Get("retry").MustString())
|
||||||
expire, _ := strconv.Atoi(model.Settings.Get("expire").MustString())
|
expire, _ := strconv.Atoi(model.Settings.Get("expire").MustString())
|
||||||
alertingSound := model.Settings.Get("sound").MustString()
|
alertingSound := model.Settings.Get("sound").MustString()
|
||||||
@ -207,17 +216,18 @@ func NewPushoverNotifier(model *models.AlertNotification) (alerting.Notifier, er
|
|||||||
return nil, alerting.ValidationError{Reason: "API token not given"}
|
return nil, alerting.ValidationError{Reason: "API token not given"}
|
||||||
}
|
}
|
||||||
return &PushoverNotifier{
|
return &PushoverNotifier{
|
||||||
NotifierBase: NewNotifierBase(model),
|
NotifierBase: NewNotifierBase(model),
|
||||||
UserKey: userKey,
|
UserKey: userKey,
|
||||||
APIToken: APIToken,
|
APIToken: APIToken,
|
||||||
Priority: priority,
|
AlertingPriority: alertingPriority,
|
||||||
Retry: retry,
|
OKPriority: okPriority,
|
||||||
Expire: expire,
|
Retry: retry,
|
||||||
Device: device,
|
Expire: expire,
|
||||||
AlertingSound: alertingSound,
|
Device: device,
|
||||||
OkSound: okSound,
|
AlertingSound: alertingSound,
|
||||||
Upload: uploadImage,
|
OKSound: okSound,
|
||||||
log: log.New("alerting.notifier.pushover"),
|
Upload: uploadImage,
|
||||||
|
log: log.New("alerting.notifier.pushover"),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,16 +235,17 @@ func NewPushoverNotifier(model *models.AlertNotification) (alerting.Notifier, er
|
|||||||
// alert notifications to Pushover
|
// alert notifications to Pushover
|
||||||
type PushoverNotifier struct {
|
type PushoverNotifier struct {
|
||||||
NotifierBase
|
NotifierBase
|
||||||
UserKey string
|
UserKey string
|
||||||
APIToken string
|
APIToken string
|
||||||
Priority int
|
AlertingPriority int
|
||||||
Retry int
|
OKPriority int
|
||||||
Expire int
|
Retry int
|
||||||
Device string
|
Expire int
|
||||||
AlertingSound string
|
Device string
|
||||||
OkSound string
|
AlertingSound string
|
||||||
Upload bool
|
OKSound string
|
||||||
log log.Logger
|
Upload bool
|
||||||
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify sends a alert notification to Pushover
|
// Notify sends a alert notification to Pushover
|
||||||
@ -322,12 +333,16 @@ func (pn *PushoverNotifier) genPushoverBody(evalContext *alerting.EvalContext, m
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add priority
|
// Add priority
|
||||||
err = w.WriteField("priority", strconv.Itoa(pn.Priority))
|
priority := pn.AlertingPriority
|
||||||
|
if evalContext.Rule.State == models.AlertStateOK {
|
||||||
|
priority = pn.OKPriority
|
||||||
|
}
|
||||||
|
err = w.WriteField("priority", strconv.Itoa(priority))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, b, err
|
return nil, b, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pn.Priority == 2 {
|
if priority == 2 {
|
||||||
err = w.WriteField("retry", strconv.Itoa(pn.Retry))
|
err = w.WriteField("retry", strconv.Itoa(pn.Retry))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, b, err
|
return nil, b, err
|
||||||
@ -350,7 +365,7 @@ func (pn *PushoverNotifier) genPushoverBody(evalContext *alerting.EvalContext, m
|
|||||||
// Add sound
|
// Add sound
|
||||||
sound := pn.AlertingSound
|
sound := pn.AlertingSound
|
||||||
if evalContext.Rule.State == models.AlertStateOK {
|
if evalContext.Rule.State == models.AlertStateOK {
|
||||||
sound = pn.OkSound
|
sound = pn.OKSound
|
||||||
}
|
}
|
||||||
if sound != "default" {
|
if sound != "default" {
|
||||||
err = w.WriteField("sound", sound)
|
err = w.WriteField("sound", sound)
|
||||||
|
@ -35,6 +35,7 @@ func TestPushoverNotifier(t *testing.T) {
|
|||||||
"apiToken": "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve",
|
"apiToken": "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve",
|
||||||
"userKey": "tzNZYf36y0ohWwXo4XoUrB61rz1A4o",
|
"userKey": "tzNZYf36y0ohWwXo4XoUrB61rz1A4o",
|
||||||
"priority": "1",
|
"priority": "1",
|
||||||
|
"okPriority": "2",
|
||||||
"sound": "pushover",
|
"sound": "pushover",
|
||||||
"okSound": "magic"
|
"okSound": "magic"
|
||||||
}`
|
}`
|
||||||
@ -54,9 +55,10 @@ func TestPushoverNotifier(t *testing.T) {
|
|||||||
So(pushoverNotifier.Type, ShouldEqual, "pushover")
|
So(pushoverNotifier.Type, ShouldEqual, "pushover")
|
||||||
So(pushoverNotifier.APIToken, ShouldEqual, "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve")
|
So(pushoverNotifier.APIToken, ShouldEqual, "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve")
|
||||||
So(pushoverNotifier.UserKey, ShouldEqual, "tzNZYf36y0ohWwXo4XoUrB61rz1A4o")
|
So(pushoverNotifier.UserKey, ShouldEqual, "tzNZYf36y0ohWwXo4XoUrB61rz1A4o")
|
||||||
So(pushoverNotifier.Priority, ShouldEqual, 1)
|
So(pushoverNotifier.AlertingPriority, ShouldEqual, 1)
|
||||||
|
So(pushoverNotifier.OKPriority, ShouldEqual, 2)
|
||||||
So(pushoverNotifier.AlertingSound, ShouldEqual, "pushover")
|
So(pushoverNotifier.AlertingSound, ShouldEqual, "pushover")
|
||||||
So(pushoverNotifier.OkSound, ShouldEqual, "magic")
|
So(pushoverNotifier.OKSound, ShouldEqual, "magic")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -67,7 +69,7 @@ func TestGenPushoverBody(t *testing.T) {
|
|||||||
Convey("Given common sounds", func() {
|
Convey("Given common sounds", func() {
|
||||||
sirenSound := "siren_sound_tst"
|
sirenSound := "siren_sound_tst"
|
||||||
successSound := "success_sound_tst"
|
successSound := "success_sound_tst"
|
||||||
notifier := &PushoverNotifier{AlertingSound: sirenSound, OkSound: successSound}
|
notifier := &PushoverNotifier{AlertingSound: sirenSound, OKSound: successSound}
|
||||||
|
|
||||||
Convey("When alert is firing - should use siren sound", func() {
|
Convey("When alert is firing - should use siren sound", func() {
|
||||||
evalContext := alerting.NewEvalContext(context.Background(),
|
evalContext := alerting.NewEvalContext(context.Background(),
|
||||||
|
Loading…
Reference in New Issue
Block a user