From 0d8ee0b3ec9aebb8ff65ed2595031a7748f67af5 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Thu, 12 Nov 2015 13:18:36 +0100 Subject: [PATCH] Fix golint issues in notify/ --- notify/impl.go | 23 ++++++++++++++++++++--- notify/notify.go | 47 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/notify/impl.go b/notify/impl.go index ff1e15d1..a177cd62 100644 --- a/notify/impl.go +++ b/notify/impl.go @@ -62,20 +62,28 @@ func Build(confs []*config.Receiver, tmpl *template.Template) map[string]Fanout const contentTypeJSON = "application/json" +// Webhook implements a Notifier for generic webhooks. type Webhook struct { + // The URL to which notifications are sent. URL string } +// NewWebhook returns a new Webhook. func NewWebhook(conf *config.WebhookConfig) *Webhook { return &Webhook{URL: conf.URL} } +// WebhookMessage defines the JSON object send to webhook endpoints. type WebhookMessage struct { - Version string `json:"version"` - Status model.AlertStatus `json:"status"` - Alerts model.Alerts `json:"alert"` + // The protocol version. + Version string `json:"version"` + // The alert status. It is firing iff any of the alerts is not resolved. + Status model.AlertStatus `json:"status"` + // A batch of alerts. + Alerts model.Alerts `json:"alert"` } +// Notify implements the Notifier interface. func (w *Webhook) Notify(ctx context.Context, alerts ...*types.Alert) error { as := types.Alerts(alerts...) @@ -103,15 +111,18 @@ func (w *Webhook) Notify(ctx context.Context, alerts ...*types.Alert) error { return nil } +// Email implements a Notifier for email notifications. type Email struct { conf *config.EmailConfig tmpl *template.Template } +// NewEmail returns a new Email notifier. func NewEmail(c *config.EmailConfig, t *template.Template) *Email { return &Email{conf: c, tmpl: t} } +// auth resolves a string of authentication mechanisms. func (n *Email) auth(mechs string) (smtp.Auth, *tls.Config, error) { username := os.Getenv("SMTP_AUTH_USERNAME") @@ -146,6 +157,7 @@ func (n *Email) auth(mechs string) (smtp.Auth, *tls.Config, error) { return nil, nil, nil } +// Notify implements the Notifier interface. func (n *Email) Notify(ctx context.Context, as ...*types.Alert) error { // Connect to the SMTP smarthost. c, err := smtp.Dial(n.conf.Smarthost) @@ -213,11 +225,13 @@ func (n *Email) Notify(ctx context.Context, as ...*types.Alert) error { return n.tmpl.ExecuteHTML(wc, n.conf.Templates.HTML, &data) } +// PagerDuty implements a Notifier for PagerDuty notifications. type PagerDuty struct { conf *config.PagerdutyConfig tmpl *template.Template } +// NewPagerDuty returns a new PagerDuty notifier. func NewPagerDuty(c *config.PagerdutyConfig, t *template.Template) *PagerDuty { return &PagerDuty{conf: c, tmpl: t} } @@ -237,6 +251,7 @@ type pagerDutyMessage struct { Details map[string]string `json:"details"` } +// Notify implements the Notifier interface. func (n *PagerDuty) Notify(ctx context.Context, as ...*types.Alert) error { // http://developer.pagerduty.com/documentation/integration/events/trigger alerts := types.Alerts(as...) @@ -307,6 +322,7 @@ func (n *PagerDuty) Notify(ctx context.Context, as ...*types.Alert) error { return nil } +// Slack implements a Notifier for Slack notifications. type Slack struct { conf *config.SlackConfig tmpl *template.Template @@ -338,6 +354,7 @@ type slackAttachmentField struct { Short bool `json:"short,omitempty"` } +// Notify implements the Notifier interface. func (n *Slack) Notify(ctx context.Context, as ...*types.Alert) error { alerts := types.Alerts(as...) var ( diff --git a/notify/notify.go b/notify/notify.go index 0a130472..f26746de 100644 --- a/notify/notify.go +++ b/notify/notify.go @@ -27,10 +27,12 @@ import ( "github.com/prometheus/alertmanager/types" ) -// The minimum timeout that is set for the context of a call +// MinTimeout is the minimum timeout that is set for the context of a call // to a notification pipeline. const MinTimeout = 10 * time.Second +// notifyKey defines a custom type with which a context is populated to +// avoid accidental collisions. type notifyKey int const ( @@ -42,68 +44,89 @@ const ( keyNow ) +// WithReceiver populates a context with a receiver. func WithReceiver(ctx context.Context, rcv string) context.Context { return context.WithValue(ctx, keyReceiver, rcv) } +// WithRepeatInterval populates a context with a repeat interval. func WithRepeatInterval(ctx context.Context, t time.Duration) context.Context { return context.WithValue(ctx, keyRepeatInterval, t) } +// WithSendResolved populates a context with a send resolved boolean. func WithSendResolved(ctx context.Context, b bool) context.Context { return context.WithValue(ctx, keySendResolved, b) } +// WithGroupKey populates a context with a group key. func WithGroupKey(ctx context.Context, fp model.Fingerprint) context.Context { return context.WithValue(ctx, keyGroupKey, fp) } +// WithGroupLabels populates a context with grouping labels. func WithGroupLabels(ctx context.Context, lset model.LabelSet) context.Context { return context.WithValue(ctx, keyGroupLabels, lset) } +// WithNow populates a context with a now timestamp. func WithNow(ctx context.Context, t time.Time) context.Context { return context.WithValue(ctx, keyNow, t) } +// Receiver extracts a receiver from the context. Iff none exists, the +// second argument is false. func Receiver(ctx context.Context) (string, bool) { v, ok := ctx.Value(keyReceiver).(string) return v, ok } +// RepeatInterval extracts a repeat interval from the context. Iff none exists, the +// second argument is false. func RepeatInterval(ctx context.Context) (time.Duration, bool) { v, ok := ctx.Value(keyRepeatInterval).(time.Duration) return v, ok } +// SendResolved extracts a send resolved boolean from the context. +// Iff none exists, the second argument is false. func SendResolved(ctx context.Context) (bool, bool) { v, ok := ctx.Value(keySendResolved).(bool) return v, ok } +// GroupKey extracts a group key from the context. Iff none exists, the +// second argument is false. func GroupKey(ctx context.Context) (model.Fingerprint, bool) { v, ok := ctx.Value(keyGroupKey).(model.Fingerprint) return v, ok } +// GroupLabels extracts grouping label set from the context. Iff none exists, the +// second argument is false. func GroupLabels(ctx context.Context) (model.LabelSet, bool) { v, ok := ctx.Value(keyGroupLabels).(model.LabelSet) return v, ok } +// Now extracts a now timestamp from the context. Iff none exists, the +// second argument is false. func Now(ctx context.Context) (time.Time, bool) { v, ok := ctx.Value(keyNow).(time.Time) return v, ok } +// A Notifier is a type which notifies about alerts under constraints of the +// given context. type Notifier interface { Notify(context.Context, ...*types.Alert) error } -// Notifiers fans out notifications to all notifiers it holds -// at once. +// Fanout sends notifications through all notifiers it holds at once. type Fanout map[string]Notifier +// Notify attempts to notify all Notifiers concurrently. It returns a types.MultiError +// if any of them fails. func (ns Fanout) Notify(ctx context.Context, alerts ...*types.Alert) error { var ( wg sync.WaitGroup @@ -137,14 +160,19 @@ func (ns Fanout) Notify(ctx context.Context, alerts ...*types.Alert) error { return nil } +// RetryNotifier accepts another notifier and retries notifying +// on error with exponential backoff. type RetryNotifier struct { notifier Notifier } +// Retry wraps the given notifier in a RetryNotifier. func Retry(n Notifier) *RetryNotifier { return &RetryNotifier{notifier: n} } +// Notify calls the underlying notifier with exponential backoff until it succeeds. +// It aborts if the context is canceled or timed out. func (n *RetryNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error { var ( i = 0 @@ -169,15 +197,20 @@ func (n *RetryNotifier) Notify(ctx context.Context, alerts ...*types.Alert) erro } } +// DedupingNotifier filters and forwards alerts to another notifier. +// Filtering happens based on a provider of NotifyInfos. +// On successful notification new NotifyInfos are set. type DedupingNotifier struct { notifies provider.Notifies notifier Notifier } +// Dedup wraps a Notifier in a DedupingNotifier that runs against the given NotifyInfo provider. func Dedup(notifies provider.Notifies, n Notifier) *DedupingNotifier { return &DedupingNotifier{notifies: notifies, notifier: n} } +// Notify implements the Notifier interface. func (n *DedupingNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error { name, ok := Receiver(ctx) if !ok { @@ -276,10 +309,11 @@ func (n *DedupingNotifier) Notify(ctx context.Context, alerts ...*types.Alert) e return n.notifies.Set(newNotifies...) } -// RoutedNotifier dispatches the alerts to one of a set of +// Router dispatches the alerts to one of a set of // named notifiers based on the name value provided in the context. type Router map[string]Notifier +// Notify implements the Notifier interface. func (rs Router) Notify(ctx context.Context, alerts ...*types.Alert) error { receiver, ok := Receiver(ctx) if !ok { @@ -301,6 +335,7 @@ type MutingNotifier struct { notifier Notifier } +// Mute wraps a notifier in a MutingNotifier with the given Muter. func Mute(m types.Muter, n Notifier) *MutingNotifier { return &MutingNotifier{Muter: m, notifier: n} } @@ -319,15 +354,19 @@ func (n *MutingNotifier) Notify(ctx context.Context, alerts ...*types.Alert) err return n.notifier.Notify(ctx, filtered...) } +// LogNotifier logs the alerts to be notified about. It forwards to another Notifier +// afterwards, if any is provided. type LogNotifier struct { log log.Logger notifier Notifier } +// Log wraps a Notifier in a LogNotifier with the given Logger. func Log(n Notifier, log log.Logger) *LogNotifier { return &LogNotifier{log: log, notifier: n} } +// Notify implements the Notifier interface. func (n *LogNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error { n.log.Debugf("notify %v", alerts)