mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
Alerting: PagerDuty receiver to let user configure fields Source, Client and Client URL (#59895)
* add support for source field * add client_url * use real host name for source placeholder
This commit is contained in:
@@ -26,6 +26,7 @@ const (
|
||||
defaultSeverity = "critical"
|
||||
defaultClass = "default"
|
||||
defaultGroup = "default"
|
||||
defaultClient = "Grafana"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -52,6 +53,9 @@ type pagerdutySettings struct {
|
||||
Component string `json:"component,omitempty" yaml:"component,omitempty"`
|
||||
Group string `json:"group,omitempty" yaml:"group,omitempty"`
|
||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||
Source string `json:"source,omitempty" yaml:"source,omitempty"`
|
||||
Client string `json:"client,omitempty" yaml:"client,omitempty"`
|
||||
ClientURL string `json:"client_url,omitempty" yaml:"client_url,omitempty"`
|
||||
}
|
||||
|
||||
func buildPagerdutySettings(fc FactoryConfig) (*pagerdutySettings, error) {
|
||||
@@ -88,7 +92,19 @@ func buildPagerdutySettings(fc FactoryConfig) (*pagerdutySettings, error) {
|
||||
if settings.Summary == "" {
|
||||
settings.Summary = DefaultMessageTitleEmbed
|
||||
}
|
||||
|
||||
if settings.Client == "" {
|
||||
settings.Client = defaultClient
|
||||
}
|
||||
if settings.ClientURL == "" {
|
||||
settings.ClientURL = "{{ .ExternalURL }}"
|
||||
}
|
||||
if settings.Source == "" {
|
||||
source, err := os.Hostname()
|
||||
if err != nil {
|
||||
source = settings.Client
|
||||
}
|
||||
settings.Source = source
|
||||
}
|
||||
return &settings, nil
|
||||
}
|
||||
|
||||
@@ -190,8 +206,8 @@ func (pn *PagerdutyNotifier) buildPagerdutyMessage(ctx context.Context, alerts m
|
||||
}
|
||||
|
||||
msg := &pagerDutyMessage{
|
||||
Client: "Grafana",
|
||||
ClientURL: pn.tmpl.ExternalURL.String(),
|
||||
Client: tmpl(pn.settings.Client),
|
||||
ClientURL: tmpl(pn.settings.ClientURL),
|
||||
RoutingKey: pn.settings.Key,
|
||||
EventAction: eventType,
|
||||
DedupKey: key.Hash(),
|
||||
@@ -200,6 +216,7 @@ func (pn *PagerdutyNotifier) buildPagerdutyMessage(ctx context.Context, alerts m
|
||||
Text: "External URL",
|
||||
}},
|
||||
Payload: pagerDutyPayload{
|
||||
Source: tmpl(pn.settings.Source),
|
||||
Component: tmpl(pn.settings.Component),
|
||||
Summary: tmpl(pn.settings.Summary),
|
||||
Severity: severity,
|
||||
@@ -224,11 +241,6 @@ func (pn *PagerdutyNotifier) buildPagerdutyMessage(ctx context.Context, alerts m
|
||||
msg.Payload.Summary = summary
|
||||
}
|
||||
|
||||
if hostname, err := os.Hostname(); err == nil {
|
||||
// TODO: should this be configured like in Prometheus AM?
|
||||
msg.Payload.Source = hostname
|
||||
}
|
||||
|
||||
if tmplErr != nil {
|
||||
pn.log.Warn("failed to template PagerDuty message", "error", tmplErr.Error())
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Payload: pagerDutyPayload{
|
||||
Summary: "[FIRING:1] (val1)",
|
||||
Source: hostname,
|
||||
Severity: "critical",
|
||||
Severity: defaultSeverity,
|
||||
Class: "default",
|
||||
Component: "Grafana",
|
||||
Group: "default",
|
||||
@@ -108,6 +108,50 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
},
|
||||
expMsgError: nil,
|
||||
},
|
||||
{
|
||||
name: "Should expand templates in fields",
|
||||
settings: `{
|
||||
"integrationKey": "abcdefgh0123456789",
|
||||
"severity" : "{{ .CommonLabels.severity }}",
|
||||
"class": "{{ .CommonLabels.class }}",
|
||||
"component": "{{ .CommonLabels.component }}",
|
||||
"group" : "{{ .CommonLabels.group }}",
|
||||
"source": "{{ .CommonLabels.source }}",
|
||||
"client": "client-{{ .CommonLabels.source }}",
|
||||
"client_url": "http://localhost:20200/{{ .CommonLabels.group }}"
|
||||
}`,
|
||||
alerts: []*types.Alert{
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1", "severity": "critical", "class": "test-class", "group": "test-group", "component": "test-component", "source": "test-source"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh"},
|
||||
},
|
||||
},
|
||||
},
|
||||
expMsg: &pagerDutyMessage{
|
||||
RoutingKey: "abcdefgh0123456789",
|
||||
DedupKey: "6e3538104c14b583da237e9693b76debbc17f0f8058ef20492e5853096cf8733",
|
||||
EventAction: "trigger",
|
||||
Payload: pagerDutyPayload{
|
||||
Summary: "[FIRING:1] (test-class test-component test-group val1 critical test-source)",
|
||||
Source: "test-source",
|
||||
Severity: "critical",
|
||||
Class: "test-class",
|
||||
Component: "test-component",
|
||||
Group: "test-group",
|
||||
CustomDetails: map[string]string{
|
||||
"firing": "\nValue: [no value]\nLabels:\n - alertname = alert1\n - class = test-class\n - component = test-component\n - group = test-group\n - lbl1 = val1\n - severity = critical\n - source = test-source\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=class%3Dtest-class&matcher=component%3Dtest-component&matcher=group%3Dtest-group&matcher=lbl1%3Dval1&matcher=severity%3Dcritical&matcher=source%3Dtest-source\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
|
||||
"num_firing": "1",
|
||||
"num_resolved": "0",
|
||||
"resolved": "",
|
||||
},
|
||||
},
|
||||
Client: "client-test-source",
|
||||
ClientURL: "http://localhost:20200/test-group",
|
||||
Links: []pagerDutyLink{{HRef: "http://localhost", Text: "External URL"}},
|
||||
},
|
||||
expMsgError: nil,
|
||||
},
|
||||
{
|
||||
name: "Default config with one alert and custom summary",
|
||||
settings: `{"integrationKey": "abcdefgh0123456789", "summary": "Alerts firing: {{ len .Alerts.Firing }}"}`,
|
||||
@@ -126,7 +170,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Payload: pagerDutyPayload{
|
||||
Summary: "Alerts firing: 1",
|
||||
Source: hostname,
|
||||
Severity: "critical",
|
||||
Severity: defaultSeverity,
|
||||
Class: "default",
|
||||
Component: "Grafana",
|
||||
Group: "default",
|
||||
@@ -206,7 +250,7 @@ func TestPagerdutyNotifier(t *testing.T) {
|
||||
Payload: pagerDutyPayload{
|
||||
Summary: fmt.Sprintf("%s…", strings.Repeat("1", 1023)),
|
||||
Source: hostname,
|
||||
Severity: "critical",
|
||||
Severity: defaultSeverity,
|
||||
Class: "default",
|
||||
Component: "Grafana",
|
||||
Group: "default",
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package channels_config
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier/channels"
|
||||
)
|
||||
|
||||
// GetAvailableNotifiers returns the metadata of all the notification channels that can be configured.
|
||||
func GetAvailableNotifiers() []*NotifierPlugin {
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
pushoverSoundOptions := []SelectOption{
|
||||
{
|
||||
Value: "default",
|
||||
@@ -242,8 +246,8 @@ func GetAvailableNotifiers() []*NotifierPlugin {
|
||||
Label: "Severity",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "critical",
|
||||
Description: "Severity of the event. It must be critical, error, warning, info - otherwise, the default is set which is critical. You can use templates",
|
||||
Placeholder: "error",
|
||||
Description: "Severity of the event. It must be critical, error, warning, info - otherwise, the default is set which is error. You can use templates",
|
||||
PropertyName: "severity",
|
||||
},
|
||||
{ // New in 8.0.
|
||||
@@ -276,6 +280,30 @@ func GetAvailableNotifiers() []*NotifierPlugin {
|
||||
Placeholder: channels.DefaultMessageTitleEmbed,
|
||||
PropertyName: "summary",
|
||||
},
|
||||
{ // New in 9.4.
|
||||
Label: "Source",
|
||||
Description: "The unique location of the affected system, preferably a hostname or FQDN. You can use templates",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: hostname,
|
||||
PropertyName: "source",
|
||||
},
|
||||
{ // New in 9.4.
|
||||
Label: "Client",
|
||||
Description: "The name of the monitoring client that is triggering this event. You can use templates",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "Grafana",
|
||||
PropertyName: "client",
|
||||
},
|
||||
{ // New in 9.4.
|
||||
Label: "Client URL",
|
||||
Description: "The URL of the monitoring client that is triggering this event. You can use templates",
|
||||
Element: ElementTypeInput,
|
||||
InputType: InputTypeText,
|
||||
Placeholder: "{{ .ExternalURL }}",
|
||||
PropertyName: "client_url",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user