From e68b37ebce9d6af54ff8bfdac1cacb55d39b2100 Mon Sep 17 00:00:00 2001 From: almostinf Date: Mon, 4 Dec 2023 11:23:20 +0300 Subject: [PATCH] refactor register notifier --- local/api.yml | 2 +- notifier/notifier.go | 6 +--- notifier/notifier_test.go | 8 +++-- notifier/registrator.go | 74 +++++++++++++++++++++------------------ 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/local/api.yml b/local/api.yml index 1b5b9834e..4368b8d70 100644 --- a/local/api.yml +++ b/local/api.yml @@ -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 diff --git a/notifier/notifier.go b/notifier/notifier.go index 3d78897f7..577cdaab2 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -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 @@ -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 @@ -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, @@ -108,7 +105,6 @@ func NewNotifier( metricSourceProvider: metricSourceProvider, imageStores: imageStoreMap, sendersNameToType: make(map[string]string), - sendersOnce: make(map[string]*sync.Once), } } @@ -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 diff --git a/notifier/notifier_test.go b/notifier/notifier_test.go index 1f3487716..879b9596f 100644 --- a/notifier/notifier_test.go +++ b/notifier/notifier_test.go @@ -29,6 +29,11 @@ var ( Location: location, DateTimeFormat: dateTimeFormat, MaxParallelSendsPerSender: 16, + Senders: []map[string]interface{}{ + { + "type": "test", + }, + }, } ) @@ -222,6 +227,7 @@ 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) @@ -229,8 +235,6 @@ func configureNotifier(t *testing.T, config Config) { 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"]) }) } diff --git a/notifier/registrator.go b/notifier/registrator.go index b8a53a60b..5798e6fc0 100644 --- a/notifier/registrator.go +++ b/notifier/registrator.go @@ -3,7 +3,6 @@ package notifier import ( "fmt" "strings" - "sync" "github.com/moira-alert/moira" "github.com/moira-alert/moira/senders/discord" @@ -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 @@ -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 } @@ -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 @@ -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)