mirror of
https://github.com/prometheus/alertmanager
synced 2024-12-27 08:32:15 +00:00
Implement initial PagerDuty notifications
This commit is contained in:
parent
6ff0cd94c5
commit
aead14a99f
@ -143,10 +143,10 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
}
|
||||
for _, pdc := range nc.PagerdutyConfigs {
|
||||
if pdc.URL == "" {
|
||||
if c.Global.PagerDutyURL == "" {
|
||||
if c.Global.PagerdutyURL == "" {
|
||||
return fmt.Errorf("no global PagerDuty URL set")
|
||||
}
|
||||
pdc.URL = c.Global.PagerDutyURL
|
||||
pdc.URL = c.Global.PagerdutyURL
|
||||
}
|
||||
}
|
||||
names[nc.Name] = struct{}{}
|
||||
@ -161,7 +161,7 @@ var DefaultGlobalConfig = GlobalConfig{
|
||||
type GlobalConfig struct {
|
||||
Smarthost string `yaml:"smarthost"`
|
||||
SlackURL string `yaml:"slack_url"`
|
||||
PagerDutyURL string `yaml:"pagerduty_url"`
|
||||
PagerdutyURL string `yaml:"pagerduty_url"`
|
||||
}
|
||||
|
||||
func (c *GlobalConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
|
@ -44,8 +44,8 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
DefaultPagerDutyConfig = PagerDutyConfig{
|
||||
Templates: PagerDutyTemplates{
|
||||
DefaultPagerdutyConfig = PagerdutyConfig{
|
||||
Templates: PagerdutyTemplates{
|
||||
Description: "pagerduty.default.description",
|
||||
},
|
||||
}
|
||||
@ -56,19 +56,19 @@ type PagerdutyConfig struct {
|
||||
ServiceKey string `yaml:"service_key"`
|
||||
URL string `yaml:"url"`
|
||||
|
||||
Templates PagerDutyTemplates `yaml:"templates"`
|
||||
Templates PagerdutyTemplates `yaml:"templates"`
|
||||
|
||||
// Catches all undefined fields and must be empty after parsing.
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
type PagerDutyTemplates struct {
|
||||
type PagerdutyTemplates struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
func (c *PagerdutyConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
*c = DefaultPagerDutyConfig
|
||||
*c = DefaultPagerdutyConfig
|
||||
type plain PagerdutyConfig
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
return err
|
||||
|
@ -51,6 +51,9 @@ func Build(confs []*config.NotificationConfig, tmpl *template.Template) map[stri
|
||||
for i, c := range nc.EmailConfigs {
|
||||
add(i, NewEmail(c, tmpl))
|
||||
}
|
||||
for i, c := range nc.PagerdutyConfigs {
|
||||
add(i, NewPagerDuty(c, tmpl))
|
||||
}
|
||||
|
||||
res[nc.Name] = fo
|
||||
}
|
||||
@ -210,6 +213,68 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) error {
|
||||
return n.tmpl.ExecuteHTML(wc, n.conf.Templates.HTML, &data)
|
||||
}
|
||||
|
||||
type PagerDuty struct {
|
||||
conf *config.PagerdutyConfig
|
||||
tmpl *template.Template
|
||||
}
|
||||
|
||||
func NewPagerDuty(c *config.PagerdutyConfig, t *template.Template) *PagerDuty {
|
||||
return &PagerDuty{conf: c, tmpl: t}
|
||||
}
|
||||
|
||||
const (
|
||||
pagerDutyEventTrigger = "trigger"
|
||||
pagerDutyEventResolve = "resolve"
|
||||
)
|
||||
|
||||
type pagerDutyMessage struct {
|
||||
ServiceKey string `json:"service_key"`
|
||||
EventType string `json:"event_type"`
|
||||
Description string `json:"description"`
|
||||
IncidentKey uint64 `json:"incident_key"`
|
||||
Client string `json:"client,omitempty"`
|
||||
ClientURL string `json:"client_url,omitempty"`
|
||||
Details map[string]string `json:"details"`
|
||||
}
|
||||
|
||||
func (pd *PagerDuty) Notify(ctx context.Context, as ...*types.Alert) error {
|
||||
// http://developer.pagerduty.com/documentation/integration/events/trigger
|
||||
alerts := types.Alerts(as...)
|
||||
|
||||
eventType := pagerDutyEventTrigger
|
||||
if alerts.Status() == model.AlertResolved {
|
||||
eventType = pagerDutyEventResolve
|
||||
}
|
||||
|
||||
msg := &pagerDutyMessage{
|
||||
ServiceKey: pd.conf.ServiceKey,
|
||||
EventType: eventType,
|
||||
IncidentKey: 123,
|
||||
Description: "",
|
||||
Details: nil,
|
||||
}
|
||||
if eventType == pagerDutyEventTrigger {
|
||||
msg.Client = "Prometheus Alertmanager"
|
||||
msg.ClientURL = ""
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := ctxhttp.Post(ctx, http.DefaultClient, pd.conf.URL, contentTypeJSON, &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode/100 != 2 {
|
||||
return fmt.Errorf("unexpected status code %v", resp.StatusCode)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Slack struct {
|
||||
conf *config.SlackConfig
|
||||
tmpl *template.Template
|
||||
|
4
route.go
4
route.go
@ -97,12 +97,14 @@ func NewRoute(cr *config.Route, parent *RouteOpts) *Route {
|
||||
matchers = append(matchers, m)
|
||||
}
|
||||
|
||||
return &Route{
|
||||
route := &Route{
|
||||
RouteOpts: opts,
|
||||
Matchers: matchers,
|
||||
Continue: cr.Continue,
|
||||
Routes: NewRoutes(cr.Routes, &opts),
|
||||
}
|
||||
|
||||
return route
|
||||
}
|
||||
|
||||
func NewRoutes(croutes []*config.Route, parent *RouteOpts) Routes {
|
||||
|
@ -24,14 +24,20 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="container-right group">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr ng-repeat="(name, val) in a.annotations | orderBy:name">
|
||||
<td>{{ name }}</td>
|
||||
<td>{{ val }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="left">
|
||||
<table class="table-flat">
|
||||
<tbody>
|
||||
<tr ng-repeat="(name, val) in a.annotations | orderBy:name">
|
||||
<td style="padding-right: 3em"><em>{{ name }}</em></td>
|
||||
<td>{{ val }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<button type="secondary" ng-click="silence(a)" small>Silence</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user