diff --git a/dispatch.go b/dispatch.go index 53c30124..9dc8483b 100644 --- a/dispatch.go +++ b/dispatch.go @@ -208,14 +208,13 @@ func (ag *aggrGroup) run(nf notifyFunc) { // point of time reference for the subsequent notification pipeline. // Calculating the current time directly is prone to avoid flaky behavior, // which usually only becomes apparent in tests. - ctx = context.WithValue(ctx, notify.NotifyTime, now) + ctx = notify.WithNow(ctx, now) - // Populate context with the destination name and group identifier. - ctx = context.WithValue(ctx, notify.NotifyName, ag.opts.SendTo) - ctx = context.WithValue(ctx, notify.NotifyGroup, ag.String()) - - ctx = context.WithValue(ctx, notify.NotifyRepeatInterval, ag.opts.RepeatInterval) - ctx = context.WithValue(ctx, notify.NotifySendResolved, ag.opts.SendResolved) + // Populate context with information needed along the pipeline. + ctx = notify.WithDestination(ctx, ag.opts.SendTo) + ctx = notify.WithGroup(ctx, ag.String()) + ctx = notify.WithRepeatInterval(ctx, ag.opts.RepeatInterval) + ctx = notify.WithSendResolved(ctx, ag.opts.SendResolved) // Wait the configured interval before calling flush again. ag.next.Reset(ag.opts.GroupInterval) diff --git a/notify/notify.go b/notify/notify.go index 61888ab5..4db4e0df 100644 --- a/notify/notify.go +++ b/notify/notify.go @@ -17,13 +17,58 @@ import ( type notifyKey int const ( - NotifyName notifyKey = iota - NotifyRepeatInterval - NotifySendResolved - NotifyGroup - NotifyTime + keyDestination notifyKey = iota + keyRepeatInterval + keySendResolved + keyGroup + keyNow ) +func WithDestination(ctx context.Context, dest string) context.Context { + return context.WithValue(ctx, keyDestination, dest) +} + +func WithRepeatInterval(ctx context.Context, t time.Duration) context.Context { + return context.WithValue(ctx, keyRepeatInterval, t) +} + +func WithSendResolved(ctx context.Context, b bool) context.Context { + return context.WithValue(ctx, keySendResolved, b) +} + +func WithGroup(ctx context.Context, g string) context.Context { + return context.WithValue(ctx, keyGroup, g) +} + +func WithNow(ctx context.Context, t time.Time) context.Context { + return context.WithValue(ctx, keyNow, t) +} + +func Destination(ctx context.Context) (string, bool) { + v, ok := ctx.Value(keyDestination).(string) + return v, ok +} + +func RepeatInterval(ctx context.Context) (time.Duration, bool) { + v, ok := ctx.Value(keyRepeatInterval).(time.Duration) + return v, ok +} + +func SendResolved(ctx context.Context) (bool, bool) { + v, ok := ctx.Value(keySendResolved).(bool) + return v, ok +} + +func Group(ctx context.Context) (string, bool) { + v, ok := ctx.Value(keyGroup).(string) + return v, ok +} + +func Now(ctx context.Context) (time.Time, bool) { + v, ok := ctx.Value(keyNow).(time.Time) + return v, ok +} + type Notifier interface { Notify(context.Context, ...*types.Alert) error } @@ -64,22 +109,22 @@ func NewDedupingNotifier(notifies provider.Notifies, n Notifier) *DedupingNotifi } func (n *DedupingNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error { - name, ok := ctx.Value(NotifyName).(string) + name, ok := Destination(ctx) if !ok { return fmt.Errorf("notifier name missing") } - repeatInterval, ok := ctx.Value(NotifyRepeatInterval).(time.Duration) + repeatInterval, ok := RepeatInterval(ctx) if !ok { return fmt.Errorf("repeat interval missing") } - sendResolved, ok := ctx.Value(NotifySendResolved).(bool) + sendResolved, ok := SendResolved(ctx) if !ok { return fmt.Errorf("send resolved missing") } - now, ok := ctx.Value(NotifyTime).(time.Time) + now, ok := Now(ctx) if !ok { return fmt.Errorf("now time missing") } @@ -185,7 +230,7 @@ func NewRoutedNotifier(build func([]*config.NotificationConfig) map[string]Notif } func (n *RoutedNotifier) Notify(ctx context.Context, alerts ...*types.Alert) error { - name, ok := ctx.Value(NotifyName).(string) + name, ok := Destination(ctx) if !ok { return fmt.Errorf("notifier name missing") } diff --git a/notify/notify_test.go b/notify/notify_test.go index ed2e5e54..aea003e6 100644 --- a/notify/notify_test.go +++ b/notify/notify_test.go @@ -39,10 +39,10 @@ func TestDedupingNotifier(t *testing.T) { ) now := time.Now() - ctx = context.WithValue(ctx, NotifyName, "name") - ctx = context.WithValue(ctx, NotifyRepeatInterval, time.Duration(100*time.Minute)) - ctx = context.WithValue(ctx, NotifySendResolved, true) - ctx = context.WithValue(ctx, NotifyTime, now) + ctx = WithDestination(ctx, "name") + ctx = WithRepeatInterval(ctx, time.Duration(100*time.Minute)) + ctx = WithSendResolved(ctx, true) + ctx = WithNow(ctx, now) alerts := []*types.Alert{ { @@ -237,7 +237,7 @@ func TestRoutedNotifier(t *testing.T) { for _, route := range []string{"3", "2", "1"} { var ( - ctx = context.WithValue(context.Background(), NotifyName, route) + ctx = WithDestination(context.Background(), route) alert = &types.Alert{ Alert: model.Alert{ Labels: model.LabelSet{"route": model.LabelValue(route)},