2015-09-25 16:14:46 +00:00
|
|
|
package main
|
2015-07-02 16:38:05 +00:00
|
|
|
|
|
|
|
import (
|
2015-09-27 11:09:02 +00:00
|
|
|
"fmt"
|
2015-09-27 10:27:32 +00:00
|
|
|
"sync"
|
|
|
|
|
2015-07-02 16:38:05 +00:00
|
|
|
"github.com/prometheus/log"
|
2015-09-24 22:14:41 +00:00
|
|
|
"golang.org/x/net/context"
|
2015-09-25 16:14:46 +00:00
|
|
|
|
2015-09-26 16:13:15 +00:00
|
|
|
"github.com/prometheus/alertmanager/config"
|
2015-09-25 16:14:46 +00:00
|
|
|
"github.com/prometheus/alertmanager/types"
|
2015-07-02 16:38:05 +00:00
|
|
|
)
|
|
|
|
|
2015-09-27 11:09:02 +00:00
|
|
|
type notifyKey int
|
|
|
|
|
|
|
|
const (
|
|
|
|
notifyName notifyKey = iota
|
|
|
|
)
|
|
|
|
|
2015-07-02 16:38:05 +00:00
|
|
|
type Notifier interface {
|
2015-09-26 12:12:55 +00:00
|
|
|
Notify(context.Context, ...*types.Alert) error
|
2015-07-02 16:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type LogNotifier struct {
|
2015-07-04 12:41:10 +00:00
|
|
|
name string
|
2015-07-02 16:38:05 +00:00
|
|
|
}
|
|
|
|
|
2015-09-26 12:12:55 +00:00
|
|
|
func (ln *LogNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error {
|
2015-07-04 12:41:10 +00:00
|
|
|
log.Infof("notify %q", ln.name)
|
|
|
|
|
2015-09-26 12:12:55 +00:00
|
|
|
for _, a := range alerts {
|
2015-09-26 15:54:49 +00:00
|
|
|
log.Infof("- %v", a)
|
2015-09-26 12:12:55 +00:00
|
|
|
}
|
2015-07-04 12:41:10 +00:00
|
|
|
return nil
|
2015-07-02 16:38:05 +00:00
|
|
|
}
|
2015-09-24 22:14:41 +00:00
|
|
|
|
2015-09-27 11:09:02 +00:00
|
|
|
// routedNotifier dispatches the alerts to one of a set of
|
|
|
|
// named notifiers based on the name value provided in the context.
|
|
|
|
type routedNotifier struct {
|
|
|
|
mtx sync.RWMutex
|
|
|
|
notifiers map[string]Notifier
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *routedNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error {
|
|
|
|
name, ok := ctx.Value(notifyName).(string)
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf("notifier name missing")
|
|
|
|
}
|
|
|
|
|
|
|
|
n.mtx.RLock()
|
|
|
|
defer n.mtx.RUnlock()
|
|
|
|
|
|
|
|
notifier, ok := n.notifiers[name]
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf("notifier %q does not exist", name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return notifier.Notify(ctx, alerts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *routedNotifier) ApplyConfig(conf *config.Config) {
|
|
|
|
n.mtx.Lock()
|
|
|
|
defer n.mtx.Unlock()
|
|
|
|
|
|
|
|
n.notifiers = map[string]Notifier{}
|
|
|
|
for _, cn := range conf.NotificationConfigs {
|
|
|
|
// TODO(fabxc): create proper notifiers.
|
|
|
|
n.notifiers[cn.Name] = &LogNotifier{name: cn.Name}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// mutingNotifier wraps a notifier and applies a Silencer
|
2015-09-27 10:27:32 +00:00
|
|
|
// before sending out an alert.
|
2015-09-27 11:09:02 +00:00
|
|
|
type mutingNotifier struct {
|
2015-09-27 10:27:32 +00:00
|
|
|
Notifier
|
|
|
|
|
|
|
|
silencer types.Silencer
|
|
|
|
}
|
|
|
|
|
2015-09-27 11:09:02 +00:00
|
|
|
func (n *mutingNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error {
|
2015-09-27 10:27:32 +00:00
|
|
|
var filtered []*types.Alert
|
|
|
|
for _, a := range alerts {
|
|
|
|
// TODO(fabxc): increment total alerts counter.
|
|
|
|
// Do not send the alert if the silencer mutes it.
|
|
|
|
if !n.silencer.Mutes(a.Labels) {
|
|
|
|
// TODO(fabxc): increment muted alerts counter.
|
|
|
|
filtered = append(filtered, a)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return n.Notifier.Notify(ctx, filtered...)
|
|
|
|
}
|