diff --git a/config/config.go b/config/config.go
index 64bd3216..ea7a34e2 100644
--- a/config/config.go
+++ b/config/config.go
@@ -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 {
diff --git a/config/notifies.go b/config/notifies.go
index c12dc445..68e54c30 100644
--- a/config/notifies.go
+++ b/config/notifies.go
@@ -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
diff --git a/notify/impl.go b/notify/impl.go
index fc1e5520..9dc7c434 100644
--- a/notify/impl.go
+++ b/notify/impl.go
@@ -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
diff --git a/route.go b/route.go
index ff0d377e..a573130d 100644
--- a/route.go
+++ b/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 {
diff --git a/ui/app/partials/alerts.html b/ui/app/partials/alerts.html
index f8c55d4e..c1e7c5a9 100644
--- a/ui/app/partials/alerts.html
+++ b/ui/app/partials/alerts.html
@@ -24,14 +24,20 @@
-
-
-
- {{ name }} |
- {{ val }} |
-
-
-
+
+
+
+
+ {{ name }} |
+ {{ val }} |
+
+
+
+
+
+
+
+