Skip to content

Commit

Permalink
refactor register notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
almostinf committed Dec 4, 2023
1 parent 991ac7d commit e68b37e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 43 deletions.
2 changes: 1 addition & 1 deletion local/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ web:
is_plotting_available: true
is_plotting_default_on: true
is_subscription_to_all_tags_available: true
is_readonly_enabled: true
is_readonly_enabled: false
notification_history:
ttl: 48h
query_limit: 10000
Expand Down
6 changes: 1 addition & 5 deletions notifier/notifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ type Notifier interface {
// StandardNotifier represent notification functionality
type StandardNotifier struct {
waitGroup sync.WaitGroup
senders map[string]moira.Sender
sendersNotificationsCh map[string]chan NotificationPackage
logger moira.Logger
database moira.Database
Expand All @@ -84,7 +83,6 @@ type StandardNotifier struct {
metricSourceProvider *metricSource.SourceProvider
imageStores map[string]moira.ImageStore
sendersNameToType map[string]string
sendersOnce map[string]*sync.Once
}

// NewNotifier is initializer for StandardNotifier
Expand All @@ -98,7 +96,6 @@ func NewNotifier(
scheduler Scheduler,
) *StandardNotifier {
return &StandardNotifier{
senders: make(map[string]moira.Sender),
sendersNotificationsCh: make(map[string]chan NotificationPackage),
logger: logger,
database: database,
Expand All @@ -108,7 +105,6 @@ func NewNotifier(
metricSourceProvider: metricSourceProvider,
imageStores: imageStoreMap,
sendersNameToType: make(map[string]string),
sendersOnce: make(map[string]*sync.Once),
}
}

Expand Down Expand Up @@ -147,7 +143,7 @@ func (notifier *StandardNotifier) Send(pkg *NotificationPackage, waitGroup *sync
// GetSenders get hash of registered notifier senders
func (notifier *StandardNotifier) GetSenders() map[string]bool {
hash := make(map[string]bool)
for key := range notifier.senders {
for key := range notifier.sendersNotificationsCh {
hash[key] = true
}
return hash
Expand Down
8 changes: 6 additions & 2 deletions notifier/notifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ var (
Location: location,
DateTimeFormat: dateTimeFormat,
MaxParallelSendsPerSender: 16,
Senders: []map[string]interface{}{
{
"type": "test",
},
},
}
)

Expand Down Expand Up @@ -222,15 +227,14 @@ func configureNotifier(t *testing.T, config Config) {
senderSettings := map[string]interface{}{
"type": "test",
}
standardNotifier.handleSender("test", sender)

sender.EXPECT().Init(senderSettings, logger, location, dateTimeFormat).Return(nil)

err := standardNotifier.RegisterSender(senderSettings, sender)

Convey("Should return one sender", t, func() {
So(err, ShouldBeNil)
So(standardNotifier.GetSenders(), ShouldResemble, map[string]bool{"test": true})
So(standardNotifier.sendersNameToType["test"], ShouldEqual, senderSettings["type"])
})
}

Expand Down
74 changes: 39 additions & 35 deletions notifier/registrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package notifier
import (
"fmt"
"strings"
"sync"

"github.com/moira-alert/moira"
"github.com/moira-alert/moira/senders/discord"
Expand Down Expand Up @@ -41,9 +40,25 @@ const (
mattermostSender = "mattermost"
)

func (notifier *StandardNotifier) registerMetrics(senderType string) {
notifier.metrics.SendersOkMetrics.RegisterMeter(senderType, getGraphiteSenderIdent(senderType), "sends_ok")
notifier.metrics.SendersFailedMetrics.RegisterMeter(senderType, getGraphiteSenderIdent(senderType), "sends_failed")
notifier.metrics.SendersDroppedNotifications.RegisterMeter(senderType, getGraphiteSenderIdent(senderType), "notifications_dropped")
}

func (notifier *StandardNotifier) handleSender(senderType string, sender moira.Sender) {
eventsChannel := make(chan NotificationPackage)
notifier.sendersNotificationsCh[senderType] = eventsChannel
notifier.registerMetrics(senderType)
notifier.runSenders(sender, eventsChannel)
}

// RegisterSenders watch on senders config and register all configured senders
func (notifier *StandardNotifier) RegisterSenders(connector moira.Database) error { //nolint
var err error
var sender moira.Sender
senders := make(map[string]moira.Sender)

for _, senderSettings := range notifier.config.Senders {
senderSettings["front_uri"] = notifier.config.FrontURL

Expand All @@ -52,7 +67,7 @@ func (notifier *StandardNotifier) RegisterSenders(connector moira.Database) erro
return fmt.Errorf("failed to get sender type from settings")
}

if sender, ok := notifier.senders[senderType]; ok {
if sender, ok = senders[senderType]; ok {
if err = notifier.RegisterSender(senderSettings, sender); err != nil {
return err
}
Expand All @@ -61,51 +76,56 @@ func (notifier *StandardNotifier) RegisterSenders(connector moira.Database) erro

switch senderType {
case mailSender:
err = notifier.RegisterSender(senderSettings, &mail.Sender{})
sender = &mail.Sender{}
case pushoverSender:
err = notifier.RegisterSender(senderSettings, &pushover.Sender{})
sender = &pushover.Sender{}
case scriptSender:
err = notifier.RegisterSender(senderSettings, &script.Sender{})
sender = &script.Sender{}
case discordSender:
err = notifier.RegisterSender(senderSettings, &discord.Sender{DataBase: connector})
sender = &discord.Sender{DataBase: connector}
case slackSender:
err = notifier.RegisterSender(senderSettings, &slack.Sender{})
sender = &slack.Sender{}
case telegramSender:
err = notifier.RegisterSender(senderSettings, &telegram.Sender{DataBase: connector})
sender = &telegram.Sender{DataBase: connector}
case msTeamsSender:
err = notifier.RegisterSender(senderSettings, &msteams.Sender{})
sender = &msteams.Sender{}
case pagerdutySender:
err = notifier.RegisterSender(senderSettings, &pagerduty.Sender{ImageStores: notifier.imageStores})
sender = &pagerduty.Sender{ImageStores: notifier.imageStores}
case twilioSmsSender, twilioVoiceSender:
err = notifier.RegisterSender(senderSettings, &twilio.Sender{})
sender = &twilio.Sender{}
case webhookSender:
err = notifier.RegisterSender(senderSettings, &webhook.Sender{})
sender = &webhook.Sender{}
case opsgenieSender:
err = notifier.RegisterSender(senderSettings, &opsgenie.Sender{ImageStores: notifier.imageStores})
sender = &opsgenie.Sender{ImageStores: notifier.imageStores}
case victoropsSender:
err = notifier.RegisterSender(senderSettings, &victorops.Sender{ImageStores: notifier.imageStores})
sender = &victorops.Sender{ImageStores: notifier.imageStores}
case mattermostSender:
err = notifier.RegisterSender(senderSettings, &mattermost.Sender{})
sender = &mattermost.Sender{}
// case "email":
// err = notifier.RegisterSender(senderSettings, &kontur.MailSender{})
// sender = &kontur.MailSender{}
// case "phone":
// err = notifier.RegisterSender(senderSettings, &kontur.SmsSender{})
// sender = &kontur.SmsSender{}
default:
return fmt.Errorf("unknown sender type [%s]", senderSettings["type"])
}

if err != nil {
if err = notifier.RegisterSender(senderSettings, sender); err != nil {
return err
}

senders[senderType] = sender
notifier.handleSender(senderType, sender)
}

if notifier.config.SelfStateEnabled {
sender = &selfstate.Sender{Database: connector}
selfStateSettings := map[string]interface{}{"type": selfStateSender}
if err = notifier.RegisterSender(selfStateSettings, &selfstate.Sender{Database: connector}); err != nil {
if err = notifier.RegisterSender(selfStateSettings, sender); err != nil {
notifier.logger.Warning().
Error(err).
Msg("Failed to register selfstate sender")
}
notifier.handleSender(selfStateSender, sender)
}

return nil
Expand All @@ -118,27 +138,11 @@ func (notifier *StandardNotifier) RegisterSender(senderSettings map[string]inter
return fmt.Errorf("failed to retrieve sender type from sender settings")
}

if _, ok := notifier.sendersOnce[senderType]; !ok {
notifier.sendersOnce[senderType] = &sync.Once{}
}

err := sender.Init(senderSettings, notifier.logger, notifier.config.Location, notifier.config.DateTimeFormat)
if err != nil {
return fmt.Errorf("failed to initialize sender [%s], err [%s]", senderType, err.Error())
}

notifier.sendersOnce[senderType].Do(func() {
eventsChannel := make(chan NotificationPackage)
notifier.sendersNotificationsCh[senderType] = eventsChannel

notifier.metrics.SendersOkMetrics.RegisterMeter(senderType, getGraphiteSenderIdent(senderType), "sends_ok")
notifier.metrics.SendersFailedMetrics.RegisterMeter(senderType, getGraphiteSenderIdent(senderType), "sends_failed")
notifier.metrics.SendersDroppedNotifications.RegisterMeter(senderType, getGraphiteSenderIdent(senderType), "notifications_dropped")
notifier.runSenders(sender, eventsChannel)
})

notifier.senders[senderType] = sender

var senderIdent string
if senderName, ok := senderSettings["name"]; ok {
senderIdent, ok = senderName.(string)
Expand Down

0 comments on commit e68b37e

Please sign in to comment.