From b7755d4d6883028c456f7a77cae4784b018040e3 Mon Sep 17 00:00:00 2001 From: Xenia Nisskhen Date: Thu, 9 Nov 2023 19:30:57 +0600 Subject: [PATCH] feat(linter): add linters and upgrade versions --- .github/workflows/lint.yml | 3 +- .golangci.yml | 7 ++ api/controller/contact.go | 7 +- api/controller/subscription.go | 5 +- api/controller/team.go | 29 +++---- api/controller/trigger.go | 11 +-- api/controller/trigger_metrics.go | 7 +- api/controller/triggers.go | 3 +- api/handler/subscription.go | 2 +- api/handler/triggers.go | 4 +- api/handler/triggers_test.go | 3 +- api/middleware/middleware_test.go | 6 +- checker/check.go | 4 +- checker/event_test.go | 1 - checker/metrics/conversion/errors_test.go | 13 +-- .../conversion/trigger_metrics_test.go | 13 ++- checker/trigger_checker.go | 7 +- checker/worker/handler.go | 3 +- database/redis/bot.go | 3 +- database/redis/contact.go | 13 +-- database/redis/last_check.go | 5 +- database/redis/locks.go | 7 +- database/redis/metric.go | 26 +++--- database/redis/metric_test.go | 2 +- database/redis/notification.go | 6 +- database/redis/notification_event.go | 7 +- database/redis/reply/check.go | 14 ++-- database/redis/reply/contact.go | 8 +- database/redis/reply/event.go | 18 +++-- database/redis/reply/metric.go | 3 +- database/redis/reply/notification.go | 10 ++- database/redis/reply/search_result.go | 10 ++- database/redis/reply/subscription.go | 3 +- database/redis/reply/team.go | 3 +- database/redis/reply/trigger.go | 7 +- database/redis/selfstate.go | 14 ++-- database/redis/subscription.go | 7 +- database/redis/tag.go | 7 +- database/redis/trigger.go | 21 ++--- database/redis/trigger_test.go | 2 +- database/redis/triggers_lock.go | 3 +- database/redis/triggers_to_check.go | 5 +- database/redis/triggers_to_reindex.go | 3 +- database/redis/unused_triggers.go | 3 +- expression/expression.go | 6 +- filter/connection/listening.go | 4 +- filter/metrics_parser.go | 6 +- filter/patterns_storage.go | 3 +- image_store/s3/init.go | 2 +- image_store/s3/store.go | 6 +- index/index_test.go | 2 +- index/mapping/trigger_test.go | 2 +- metric_source/local/errors.go | 4 +- metric_source/local/eval.go | 2 +- metric_source/remote/request.go | 3 +- metrics/graphite.go | 2 +- notifier/events/event.go | 3 +- notifier/notifications/notifications.go | 2 +- notifier/notifier.go | 4 +- notifier/plotting.go | 4 +- notifier/registrator.go | 2 +- notifier/scheduler.go | 2 +- notifier/selfstate/heartbeat/filter_test.go | 2 +- .../selfstate/heartbeat/local_checker_test.go | 2 +- .../heartbeat/remote_checker_test.go | 2 +- .../filter/filter_plain_metrics_test.go | 2 +- plotting/curve.go | 8 +- plotting/fonts/ttftogofile/ttf2gofile.go | 1 + plotting/limits.go | 8 +- plotting/plot_test.go | 4 +- plotting/threshold.go | 80 ++++++++++--------- plotting/threshold_test.go | 2 +- senders/discord/init.go | 2 +- senders/discord/response.go | 4 +- senders/discord/send.go | 2 +- senders/mail/send.go | 2 +- senders/mail/send_test.go | 1 - senders/mattermost/sender.go | 4 +- senders/msteams/datatypes.go | 4 +- senders/msteams/msteams.go | 11 +-- senders/opsgenie/init.go | 2 +- senders/opsgenie/send_test.go | 2 +- senders/pagerduty/send.go | 2 +- senders/pushover/pushover_test.go | 2 +- senders/script/script.go | 2 +- senders/slack/slack.go | 2 +- senders/telegram/send.go | 4 +- senders/telegram/send_test.go | 10 ++- senders/twilio/sms.go | 2 +- senders/victorops/api/alert.go | 7 +- senders/victorops/send.go | 2 +- senders/webhook/request.go | 5 +- templating/templating.go | 2 +- worker/worker.go | 2 +- 94 files changed, 327 insertions(+), 257 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3905b2673..e7a47327b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,7 +16,6 @@ jobs: - name: Run linter uses: golangci/golangci-lint-action@v3 with: - # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.54.2 + version: v1.55.2 only-new-issues: true diff --git a/.golangci.yml b/.golangci.yml index cff12d45a..d2ab6ab02 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -21,6 +21,7 @@ linters-settings: ignored-numbers: 1,2,3,5,10,60,64,100,600,0755,0644,0666 linters: + tests: false # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint disable-all: true enable: @@ -28,8 +29,11 @@ linters: - asciicheck - bidichk - bodyclose + - decorder + - depguard - dogsled - errcheck + - errorlint - goconst - gocyclo - gofmt @@ -38,9 +42,11 @@ linters: - gosimple - govet - ineffassign + - loggercheck - makezero - misspell - nilerr + - noctx - prealloc - promlinter - staticcheck @@ -55,6 +61,7 @@ issues: - path: _test\.go linters: - gomnd + - errcheck run: timeout: 5m diff --git a/api/controller/contact.go b/api/controller/contact.go index 1011a3518..eb54d79fe 100644 --- a/api/controller/contact.go +++ b/api/controller/contact.go @@ -2,6 +2,7 @@ package controller import ( "bytes" + "errors" "fmt" "time" @@ -96,7 +97,7 @@ func UpdateContact(dataBase moira.Database, contactDTO dto.Contact, contactData // RemoveContact deletes notification contact for current user and remove contactID from all subscriptions func RemoveContact(database moira.Database, contactID string, userLogin string, teamID string) *api.ErrorResponse { //nolint:gocyclo - subscriptionIDs := []string{} + var subscriptionIDs []string if userLogin != "" { userSubscriptionIDs, err := database.GetUserSubscriptionIDs(userLogin) if err != nil { @@ -179,7 +180,7 @@ func SendTestContactNotification(dataBase moira.Database, contactID string) *api func CheckUserPermissionsForContact(dataBase moira.Database, contactID string, userLogin string) (moira.ContactData, *api.ErrorResponse) { contactData, err := dataBase.GetContact(contactID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return moira.ContactData{}, api.ErrorNotFound(fmt.Sprintf("contact with ID '%s' does not exists", contactID)) } return moira.ContactData{}, api.ErrorInternalServer(err) @@ -201,7 +202,7 @@ func CheckUserPermissionsForContact(dataBase moira.Database, contactID string, u func isContactExists(dataBase moira.Database, contactID string) (bool, error) { _, err := dataBase.GetContact(contactID) - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return false, nil } if err != nil { diff --git a/api/controller/subscription.go b/api/controller/subscription.go index 4444a7b43..7c2b78829 100644 --- a/api/controller/subscription.go +++ b/api/controller/subscription.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "fmt" "time" @@ -107,7 +108,7 @@ func SendTestNotification(database moira.Database, subscriptionID string) *api.E func CheckUserPermissionsForSubscription(dataBase moira.Database, subscriptionID string, userLogin string) (moira.SubscriptionData, *api.ErrorResponse) { subscription, err := dataBase.GetSubscription(subscriptionID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return moira.SubscriptionData{}, api.ErrorNotFound(fmt.Sprintf("subscription with ID '%s' does not exists", subscriptionID)) } return moira.SubscriptionData{}, api.ErrorInternalServer(err) @@ -129,7 +130,7 @@ func CheckUserPermissionsForSubscription(dataBase moira.Database, subscriptionID func isSubscriptionExists(dataBase moira.Database, subscriptionID string) (bool, error) { _, err := dataBase.GetSubscription(subscriptionID) - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return false, nil } if err != nil { diff --git a/api/controller/team.go b/api/controller/team.go index e239e8d08..eab97b01b 100644 --- a/api/controller/team.go +++ b/api/controller/team.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "fmt" "strings" @@ -24,7 +25,7 @@ func CreateTeam(dataBase moira.Database, team dto.TeamModel, userID string) (dto if err == nil { return dto.SaveTeamResponse{}, api.ErrorInvalidRequest(fmt.Errorf("team with ID you specified already exists %s", teamID)) } - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return dto.SaveTeamResponse{}, api.ErrorInternalServer(fmt.Errorf("cannot check id for team: %w", err)) } } else { // on the other hand try to create an UUID for teamID @@ -36,7 +37,7 @@ func CreateTeam(dataBase moira.Database, team dto.TeamModel, userID string) (dto } teamID = generatedUUID.String() _, err = dataBase.GetTeam(teamID) - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { createdSuccessfully = true break } @@ -71,7 +72,7 @@ func GetTeam(dataBase moira.Database, teamID string) (dto.TeamModel, *api.ErrorR team, err := dataBase.GetTeam(teamID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamModel{}, api.ErrorNotFound(fmt.Sprintf("cannot find team: %s", teamID)) } return dto.TeamModel{}, api.ErrorInternalServer(fmt.Errorf("cannot get team from database: %w", err)) @@ -86,7 +87,7 @@ func GetUserTeams(dataBase moira.Database, userID string) (dto.UserTeams, *api.E teams, err := dataBase.GetUserTeams(userID) result := []dto.TeamModel{} - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return dto.UserTeams{}, api.ErrorInternalServer(fmt.Errorf("cannot get user teams from database: %w", err)) } @@ -107,7 +108,7 @@ func GetTeamUsers(dataBase moira.Database, teamID string) (dto.TeamMembers, *api users, err := dataBase.GetTeamUsers(teamID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamMembers{}, api.ErrorNotFound(fmt.Sprintf("cannot find team users: %s", teamID)) } return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get team users from database: %w", err)) @@ -151,8 +152,8 @@ func addTeamsForNewUsers(dataBase moira.Database, teamID string, newUsers map[st if _, ok := teamsMap[userID]; ok { continue } - fetchedUserTeams, err := dataBase.GetUserTeams(userID) //nolint:govet - if err != nil && err != database.ErrNil { + fetchedUserTeams, err := dataBase.GetUserTeams(userID) + if err != nil && !errors.Is(err, database.ErrNil) { return nil, api.ErrorInternalServer(fmt.Errorf("cannot get team users from database: %w", err)) } fetchedUserTeams = append(fetchedUserTeams, teamID) @@ -165,7 +166,7 @@ func addTeamsForNewUsers(dataBase moira.Database, teamID string, newUsers map[st func SetTeamUsers(dataBase moira.Database, teamID string, allUsers []string) (dto.TeamMembers, *api.ErrorResponse) { existingUsers, err := dataBase.GetTeamUsers(teamID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamMembers{}, api.ErrorNotFound(fmt.Sprintf("cannot find team users: %s", teamID)) } return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get team users from database: %w", err)) @@ -241,7 +242,7 @@ func addUserTeam(teamID string, teams []string) ([]string, error) { func AddTeamUsers(dataBase moira.Database, teamID string, newUsers []string) (dto.TeamMembers, *api.ErrorResponse) { existingUsers, err := dataBase.GetTeamUsers(teamID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamMembers{}, api.ErrorNotFound(fmt.Sprintf("cannot find team users: %s", teamID)) } return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get team users from database: %w", err)) @@ -253,7 +254,7 @@ func AddTeamUsers(dataBase moira.Database, teamID string, newUsers []string) (dt for _, userID := range existingUsers { userTeams, err := dataBase.GetUserTeams(userID) //nolint:govet if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamMembers{}, api.ErrorNotFound(fmt.Sprintf("cannot find user teams: %s", userID)) } return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get user teams from database: %w", err)) @@ -268,7 +269,7 @@ func AddTeamUsers(dataBase moira.Database, teamID string, newUsers []string) (dt } userTeams, err := dataBase.GetUserTeams(userID) //nolint:govet - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get user teams from database: %w", err)) } @@ -335,7 +336,7 @@ func DeleteTeam(dataBase moira.Database, teamID, userLogin string) (dto.SaveTeam func DeleteTeamUser(dataBase moira.Database, teamID string, removeUserID string) (dto.TeamMembers, *api.ErrorResponse) { existingUsers, err := dataBase.GetTeamUsers(teamID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamMembers{}, api.ErrorNotFound(fmt.Sprintf("cannot find team users: %s", teamID)) } return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get team users from database: %w", err)) @@ -361,7 +362,7 @@ func DeleteTeamUser(dataBase moira.Database, teamID string, removeUserID string) for _, userID := range existingUsers { userTeams, err := dataBase.GetUserTeams(userID) //nolint:govet if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return dto.TeamMembers{}, api.ErrorNotFound(fmt.Sprintf("cannot find user teams: %s", userID)) } return dto.TeamMembers{}, api.ErrorInternalServer(fmt.Errorf("cannot get user teams from database: %w", err)) @@ -402,7 +403,7 @@ func removeUserTeam(teams []string, teamID string) ([]string, error) { func CheckUserPermissionsForTeam(dataBase moira.Database, teamID, userID string) *api.ErrorResponse { _, err := dataBase.GetTeam(teamID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return api.ErrorNotFound(fmt.Sprintf("team with ID '%s' does not exists", teamID)) } return api.ErrorInternalServer(err) diff --git a/api/controller/trigger.go b/api/controller/trigger.go index fa0c7d1a7..d2cc2d5d9 100644 --- a/api/controller/trigger.go +++ b/api/controller/trigger.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "fmt" "time" @@ -17,7 +18,7 @@ const maxTriggerLockAttempts = 10 func UpdateTrigger(dataBase moira.Database, trigger *dto.TriggerModel, triggerID string, timeSeriesNames map[string]bool) (*dto.SaveTriggerResponse, *api.ErrorResponse) { _, err := dataBase.GetTrigger(triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return nil, api.ErrorNotFound(fmt.Sprintf("trigger with ID = '%s' does not exists", triggerID)) } return nil, api.ErrorInternalServer(err) @@ -32,11 +33,11 @@ func saveTrigger(dataBase moira.Database, trigger *moira.Trigger, triggerID stri } defer dataBase.DeleteTriggerCheckLock(triggerID) //nolint lastCheck, err := dataBase.GetTriggerLastCheck(triggerID) - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return nil, api.ErrorInternalServer(err) } - if err != database.ErrNil { + if !errors.Is(err, database.ErrNil) { for metric := range lastCheck.Metrics { if _, ok := timeSeriesNames[metric]; !ok { lastCheck.RemoveMetricState(metric) @@ -74,7 +75,7 @@ func saveTrigger(dataBase moira.Database, trigger *moira.Trigger, triggerID stri func GetTrigger(dataBase moira.Database, triggerID string) (*dto.Trigger, *api.ErrorResponse) { trigger, err := dataBase.GetTrigger(triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return nil, api.ErrorNotFound("trigger not found") } return nil, api.ErrorInternalServer(err) @@ -131,7 +132,7 @@ func GetTriggerLastCheck(dataBase moira.Database, triggerID string) (*dto.Trigge *lastCheck, err = dataBase.GetTriggerLastCheck(triggerID) if err != nil { - if err != database.ErrNil { + if !errors.Is(err, database.ErrNil) { return nil, api.ErrorInternalServer(err) } lastCheck = nil diff --git a/api/controller/trigger_metrics.go b/api/controller/trigger_metrics.go index bb74c88d9..914460efe 100644 --- a/api/controller/trigger_metrics.go +++ b/api/controller/trigger_metrics.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "fmt" "github.com/moira-alert/moira" @@ -51,7 +52,7 @@ func DeleteTriggerNodataMetrics(dataBase moira.Database, triggerID string) *api. func GetTriggerMetrics(dataBase moira.Database, metricSourceProvider *metricSource.SourceProvider, from, to int64, triggerID string) (*dto.TriggerMetrics, *api.ErrorResponse) { tts, _, err := GetTriggerEvaluationResult(dataBase, metricSourceProvider, from, to, triggerID, false) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return nil, api.ErrorInvalidRequest(fmt.Errorf("trigger not found")) } return nil, api.ErrorInternalServer(err) @@ -79,7 +80,7 @@ func GetTriggerMetrics(dataBase moira.Database, metricSourceProvider *metricSour func deleteTriggerMetrics(dataBase moira.Database, metricName string, triggerID string, removeAllNodataMetrics bool) *api.ErrorResponse { trigger, err := dataBase.GetTrigger(triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return api.ErrorInvalidRequest(fmt.Errorf("trigger not found")) } return api.ErrorInternalServer(err) @@ -92,7 +93,7 @@ func deleteTriggerMetrics(dataBase moira.Database, metricName string, triggerID lastCheck, err := dataBase.GetTriggerLastCheck(triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return api.ErrorInvalidRequest(fmt.Errorf("trigger check not found")) } return api.ErrorInternalServer(err) diff --git a/api/controller/triggers.go b/api/controller/triggers.go index 5d4d45c56..eecbe04c7 100644 --- a/api/controller/triggers.go +++ b/api/controller/triggers.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "fmt" "math" "regexp" @@ -200,7 +201,7 @@ func getTriggerChecks(database moira.Database, triggerIDs []string) ([]moira.Tri func triggerExists(database moira.Database, triggerID string) (bool, error) { _, err := database.GetTrigger(triggerID) - if err == db.ErrNil { + if errors.Is(err, db.ErrNil) { return false, nil } if err != nil { diff --git a/api/handler/subscription.go b/api/handler/subscription.go index 833abbfb5..6404d3555 100644 --- a/api/handler/subscription.go +++ b/api/handler/subscription.go @@ -120,7 +120,7 @@ func subscriptionFilter(next http.Handler) http.Handler { func updateSubscription(writer http.ResponseWriter, request *http.Request) { subscription := &dto.Subscription{} if err := render.Bind(request, subscription); err != nil { - switch err.(type) { + switch err.(type) { // nolint:errorlint case dto.ErrProvidedContactsForbidden: render.Render(writer, request, api.ErrorForbidden(err.Error())) //nolint default: diff --git a/api/handler/triggers.go b/api/handler/triggers.go index c16f56bdd..1a60d8758 100644 --- a/api/handler/triggers.go +++ b/api/handler/triggers.go @@ -151,7 +151,7 @@ func createTrigger(writer http.ResponseWriter, request *http.Request) { func getTriggerFromRequest(request *http.Request) (*dto.Trigger, *api.ErrorResponse) { trigger := &dto.Trigger{} if err := render.Bind(request, trigger); err != nil { - switch err.(type) { + switch err.(type) { // nolint:errorlint case local.ErrParseExpr, local.ErrEvalExpr, local.ErrUnknownFunction: return nil, api.ErrorInvalidRequest(fmt.Errorf("invalid graphite targets: %s", err.Error())) case expression.ErrInvalidExpression: @@ -211,7 +211,7 @@ func triggerCheck(writer http.ResponseWriter, request *http.Request) { response := dto.TriggerCheckResponse{} if err := render.Bind(request, trigger); err != nil { - switch err.(type) { + switch err.(type) { // nolint:errorlint case expression.ErrInvalidExpression, local.ErrParseExpr, local.ErrEvalExpr, local.ErrUnknownFunction: // TODO write comment, why errors are ignored, it is not obvious. // In getTriggerFromRequest these types of errors lead to 400. diff --git a/api/handler/triggers_test.go b/api/handler/triggers_test.go index 4246f7de0..61d3680f7 100644 --- a/api/handler/triggers_test.go +++ b/api/handler/triggers_test.go @@ -2,6 +2,7 @@ package handler import ( "bytes" + "context" "encoding/json" "fmt" "io" @@ -39,7 +40,7 @@ func TestGetSearchRequestString(t *testing.T) { {"QueRy", "query"}, } for _, testCase := range testCases { - req, _ := http.NewRequest("GET", fmt.Sprintf("/api/trigger/search?onlyProblems=false&p=0&size=20&text=%s", testCase.text), nil) + req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, fmt.Sprintf("/api/trigger/search?onlyProblems=false&p=0&size=20&text=%s", testCase.text), nil) searchRequest := getSearchRequestString(req) So(searchRequest, ShouldEqual, testCase.expectedSearchRequest) } diff --git a/api/middleware/middleware_test.go b/api/middleware/middleware_test.go index 02b6cd88b..bf8fbb47b 100644 --- a/api/middleware/middleware_test.go +++ b/api/middleware/middleware_test.go @@ -10,13 +10,13 @@ import ( func TestGetLogin(t *testing.T) { Convey("Request does not contain login, should get anonymous", t, func() { - req, err := http.NewRequest(http.MethodGet, "https://testurl.com", http.NoBody) + req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://testurl.com", http.NoBody) So(err, ShouldBeNil) So(anonymousUser, ShouldEqual, GetLogin(req)) }) Convey("Request contains login, but empty, should get anonymous", t, func() { - req, err := http.NewRequest(http.MethodGet, "https://testurl.com", http.NoBody) + req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://testurl.com", http.NoBody) ctx := context.WithValue(req.Context(), loginKey, "") req = req.WithContext(ctx) So(err, ShouldBeNil) @@ -24,7 +24,7 @@ func TestGetLogin(t *testing.T) { }) Convey("Request contains login header, should get that", t, func() { - req, err := http.NewRequest(http.MethodGet, "https://testurl.com", http.NoBody) + req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://testurl.com", http.NoBody) ctx := context.WithValue(req.Context(), loginKey, "awesome_user") req = req.WithContext(ctx) So(err, ShouldBeNil) diff --git a/checker/check.go b/checker/check.go index b1493a82b..c04dbb3b8 100644 --- a/checker/check.go +++ b/checker/check.go @@ -75,7 +75,7 @@ const ( // is not serious and check process can be continued first return value became CanContinueCheck and Filled CheckData returned. // in the other case first return value became MustStopCheck and error passed to this function is handled. func (triggerChecker *TriggerChecker) handlePrepareError(checkData moira.CheckData, err error) (ErrorSeverity, moira.CheckData, error) { - switch err.(type) { + switch err.(type) { // nolint:errorlint case ErrTriggerHasSameMetricNames: checkData.State = moira.StateEXCEPTION checkData.Message = err.Error() @@ -112,7 +112,7 @@ func (triggerChecker *TriggerChecker) handlePrepareError(checkData moira.CheckDa // handleFetchError is a function that checks error returned from fetchTriggerMetrics function. func (triggerChecker *TriggerChecker) handleFetchError(checkData moira.CheckData, err error) error { - switch err.(type) { + switch err.(type) { // nolint:errorlint case ErrTriggerHasEmptyTargets, ErrTriggerHasOnlyWildcards: triggerChecker.logger.Debug(). String(moira.LogFieldNameTriggerID, triggerChecker.triggerID). diff --git a/checker/event_test.go b/checker/event_test.go index 1e63113dc..4be41ca01 100644 --- a/checker/event_test.go +++ b/checker/event_test.go @@ -406,7 +406,6 @@ func TestCheckMetricStateSuppressedState(t *testing.T) { actual, err := triggerChecker.compareMetricStates("super.awesome.metric", secondState, firstState) So(err, ShouldBeNil) secondState.EventTimestamp = firstState.EventTimestamp - //secondState.SuppressedState = firstState.SuppressedState So(actual, ShouldResemble, secondState) Convey("Test state change state after suppressed", func() { diff --git a/checker/metrics/conversion/errors_test.go b/checker/metrics/conversion/errors_test.go index d8d3b2fbd..2c8820e38 100644 --- a/checker/metrics/conversion/errors_test.go +++ b/checker/metrics/conversion/errors_test.go @@ -1,6 +1,7 @@ package conversion import ( + "errors" "strings" "testing" @@ -65,11 +66,13 @@ func TestErrUnexpectedAloneMetricBuilder(t *testing.T) { builder.setDeclared(map[string]bool{"t1": true}) builder.addUnexpected("t1", map[string]metricsource.MetricData{"metric.test.1": {Name: "metric.test.1"}, "metric.test.unexpected": {Name: "metric.test.unexpected"}}) err := builder.build() - So(err.(ErrUnexpectedAloneMetric).declared, ShouldResemble, map[string]bool{"t1": true}) - So(err.(ErrUnexpectedAloneMetric).unexpected, ShouldContainKey, "t1") - So(err.(ErrUnexpectedAloneMetric).unexpected["t1"], ShouldHaveLength, 2) - So(err.(ErrUnexpectedAloneMetric).unexpected["t1"], ShouldContain, "metric.test.1") - So(err.(ErrUnexpectedAloneMetric).unexpected["t1"], ShouldContain, "metric.test.unexpected") + var convertedErr ErrUnexpectedAloneMetric + errors.As(err, &convertedErr) + So(convertedErr.declared, ShouldResemble, map[string]bool{"t1": true}) + So(convertedErr.unexpected, ShouldContainKey, "t1") + So(convertedErr.unexpected["t1"], ShouldHaveLength, 2) + So(convertedErr.unexpected["t1"], ShouldContain, "metric.test.1") + So(convertedErr.unexpected["t1"], ShouldContain, "metric.test.unexpected") }) Convey("nil returned", func() { err := builder.build() diff --git a/checker/metrics/conversion/trigger_metrics_test.go b/checker/metrics/conversion/trigger_metrics_test.go index e6baf929d..5ff709e22 100644 --- a/checker/metrics/conversion/trigger_metrics_test.go +++ b/checker/metrics/conversion/trigger_metrics_test.go @@ -4,6 +4,8 @@ import ( "math" "testing" + "github.com/pkg/errors" + "github.com/moira-alert/moira" metricSource "github.com/moira-alert/moira/metric_source" . "github.com/smartystreets/goconvey/convey" @@ -307,10 +309,13 @@ func TestTriggerMetrics_FilterAloneMetrics(t *testing.T) { So(filtered, ShouldBeEmpty) So(alone, ShouldBeEmpty) So(err, ShouldBeError) - So(err.(ErrUnexpectedAloneMetric).unexpected, ShouldContainKey, "t2") - So(err.(ErrUnexpectedAloneMetric).unexpected["t2"], ShouldHaveLength, 2) - So(err.(ErrUnexpectedAloneMetric).unexpected["t2"], ShouldContain, "metric.test.3") - So(err.(ErrUnexpectedAloneMetric).unexpected["t2"], ShouldContain, "metric.test.4") + + var convertedErr ErrUnexpectedAloneMetric + errors.As(err, &convertedErr) + So(convertedErr.unexpected, ShouldContainKey, "t2") + So(convertedErr.unexpected["t2"], ShouldHaveLength, 2) + So(convertedErr.unexpected["t2"], ShouldContain, "metric.test.3") + So(convertedErr.unexpected["t2"], ShouldContain, "metric.test.4") }) Convey("origin has targets that declared as alone metrics but it is empty", func() { m := TriggerMetrics{ diff --git a/checker/trigger_checker.go b/checker/trigger_checker.go index 5cb738f0f..3763d67bd 100644 --- a/checker/trigger_checker.go +++ b/checker/trigger_checker.go @@ -1,6 +1,7 @@ package checker import ( + "errors" "time" "github.com/moira-alert/moira" @@ -42,7 +43,7 @@ func MakeTriggerChecker( until := time.Now().Unix() trigger, err := dataBase.GetTrigger(triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return nil, ErrTriggerNotExists } return nil, err @@ -89,11 +90,11 @@ func MakeTriggerChecker( func getLastCheck(dataBase moira.Database, triggerID string, emptyLastCheckTimestamp int64) (*moira.CheckData, error) { lastCheck, err := dataBase.GetTriggerLastCheck(triggerID) - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return nil, err } - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { lastCheck = moira.CheckData{ Metrics: make(map[string]moira.MetricState), State: moira.StateOK, diff --git a/checker/worker/handler.go b/checker/worker/handler.go index dddb81c6d..ac688d27b 100644 --- a/checker/worker/handler.go +++ b/checker/worker/handler.go @@ -1,6 +1,7 @@ package worker import ( + "errors" "fmt" "runtime/debug" "time" @@ -73,7 +74,7 @@ func (check *Checker) checkTrigger(triggerID string) error { check.Metrics, ) - if err == checker.ErrTriggerNotExists { + if errors.Is(err, checker.ErrTriggerNotExists) { return nil } if err != nil { diff --git a/database/redis/bot.go b/database/redis/bot.go index b9863c141..b1adec922 100644 --- a/database/redis/bot.go +++ b/database/redis/bot.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "strings" @@ -16,7 +17,7 @@ func (connector *DbConnector) GetIDByUsername(messenger, username string) (strin } c := *connector.client result, err := c.Get(connector.context, usernameKey(messenger, username)).Result() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return result, database.ErrNil } return result, err diff --git a/database/redis/contact.go b/database/redis/contact.go index 7521b0680..d30d20920 100644 --- a/database/redis/contact.go +++ b/database/redis/contact.go @@ -3,6 +3,7 @@ package redis import ( "context" "encoding/json" + "errors" "fmt" "strings" @@ -19,7 +20,7 @@ func (connector *DbConnector) GetContact(id string) (moira.ContactData, error) { var contact moira.ContactData result := c.Get(connector.context, contactKey(id)) - if result.Err() == redis.Nil { + if errors.Is(result.Err(), redis.Nil) { return contact, database.ErrNil } contact, err := reply.Contact(result) @@ -42,7 +43,7 @@ func (connector *DbConnector) GetContacts(contactIDs []string) ([]*moira.Contact results = append(results, result) } _, err := pipe.Exec(connector.context) - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return nil, err } @@ -108,7 +109,7 @@ func (connector *DbConnector) GetAllContacts() ([]*moira.ContactData, error) { // SaveContact writes contact data and updates user contacts func (connector *DbConnector) SaveContact(contact *moira.ContactData) error { existing, getContactErr := connector.GetContact(contact.ID) - if getContactErr != nil && getContactErr != database.ErrNil { + if getContactErr != nil && !errors.Is(getContactErr, database.ErrNil) { return getContactErr } contactString, err := json.Marshal(contact) @@ -120,10 +121,10 @@ func (connector *DbConnector) SaveContact(contact *moira.ContactData) error { pipe := c.TxPipeline() pipe.Set(connector.context, contactKey(contact.ID), contactString, redis.KeepTTL) - if getContactErr != database.ErrNil && contact.User != existing.User { + if !errors.Is(getContactErr, database.ErrNil) && contact.User != existing.User { pipe.SRem(connector.context, userContactsKey(existing.User), contact.ID) } - if getContactErr != database.ErrNil && contact.Team != existing.Team { + if !errors.Is(getContactErr, database.ErrNil) && contact.Team != existing.Team { pipe.SRem(connector.context, teamContactsKey(existing.Team), contact.ID) } if contact.User != "" { @@ -142,7 +143,7 @@ func (connector *DbConnector) SaveContact(contact *moira.ContactData) error { // RemoveContact deletes contact data and contactID from user contacts func (connector *DbConnector) RemoveContact(contactID string) error { existing, err := connector.GetContact(contactID) - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return err } c := *connector.client diff --git a/database/redis/last_check.go b/database/redis/last_check.go index 21ac48aeb..ed357bca4 100644 --- a/database/redis/last_check.go +++ b/database/redis/last_check.go @@ -3,6 +3,7 @@ package redis import ( "context" "encoding/json" + "errors" "fmt" "strings" "time" @@ -114,7 +115,7 @@ func cleanUpAbandonedTriggerLastCheckOnRedisNode(connector *DbConnector, client lastCheckKey := lastCheckIterator.Val() triggerID := strings.TrimPrefix(lastCheckKey, metricLastCheckKey("")) _, err := connector.GetTrigger(triggerID) - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { err = connector.RemoveTriggerLastCheck(triggerID) if err != nil { return err @@ -152,7 +153,7 @@ func (connector *DbConnector) SetTriggerCheckMaintenance(triggerID string, metri lastCheckString, readingErr := c.Get(ctx, metricLastCheckKey(triggerID)).Result() if readingErr != nil { - if readingErr != redis.Nil { + if !errors.Is(readingErr, redis.Nil) { return readingErr } return nil diff --git a/database/redis/locks.go b/database/redis/locks.go index f4b7c3a89..de0f98646 100644 --- a/database/redis/locks.go +++ b/database/redis/locks.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "sync" "time" @@ -35,13 +36,13 @@ func (lock *Lock) Acquire(stop <-chan struct{}) (<-chan struct{}, error) { return lost, nil } - if err == database.ErrLockAlreadyHeld { + if errors.Is(err, database.ErrLockAlreadyHeld) { return nil, database.ErrLockAlreadyHeld } - switch e := err.(type) { + switch e := err.(type) { // nolint:errorlint case *database.ErrLockNotAcquired: - if e.Err != redsync.ErrFailed { + if !errors.Is(e.Err, redsync.ErrFailed) { return nil, err } } diff --git a/database/redis/metric.go b/database/redis/metric.go index a0e349d8a..02b514a87 100644 --- a/database/redis/metric.go +++ b/database/redis/metric.go @@ -60,7 +60,7 @@ func (connector *DbConnector) GetMetricRetention(metric string) (int64, error) { } retention, err := connector.getMetricRetention(metric) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return retention, nil } return retention, err @@ -83,7 +83,7 @@ func (connector *DbConnector) getMetricRetention(metric string) (int64, error) { retentionStr, err := c.Get(connector.context, metricRetentionKey(metric)).Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return 60, database.ErrNil //nolint } return 0, fmt.Errorf("failed GET metric retention:%s, error: %w", metric, err) @@ -217,7 +217,7 @@ const ( func (connector *DbConnector) handlePopResponse(data []string, popError error, responseChannel chan string, defaultDelay time.Duration) time.Duration { if popError != nil { - if popError != redis.Nil { + if !errors.Is(popError, redis.Nil) { connector.logger.Error(). Error(popError). Msg("Failed to pop new metric events") @@ -238,7 +238,7 @@ func (connector *DbConnector) handlePopResponse(data []string, popError error, r func (connector *DbConnector) AddPatternMetric(pattern, metric string) error { c := *connector.client if _, err := c.SAdd(connector.context, patternMetricsKey(pattern), metric).Result(); err != nil { - return fmt.Errorf("failed to SADD pattern-metrics, pattern: %s, metric: %s, error: %v", pattern, metric, err) + return fmt.Errorf("failed to SADD pattern-metrics, pattern: %s, metric: %s, error: %w", pattern, metric, err) } return nil } @@ -249,10 +249,10 @@ func (connector *DbConnector) GetPatternMetrics(pattern string) ([]string, error metrics, err := c.SMembers(connector.context, patternMetricsKey(pattern)).Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]string, 0), nil } - return nil, fmt.Errorf("failed to get pattern metrics for pattern %s, error: %v", pattern, err) + return nil, fmt.Errorf("failed to get pattern metrics for pattern %s, error: %w", pattern, err) } return metrics, nil } @@ -261,7 +261,7 @@ func (connector *DbConnector) GetPatternMetrics(pattern string) ([]string, error func (connector *DbConnector) RemovePattern(pattern string) error { c := *connector.client if _, err := c.SRem(connector.context, patternsListKey, pattern).Result(); err != nil { - return fmt.Errorf("failed to remove pattern: %s, error: %v", pattern, err) + return fmt.Errorf("failed to remove pattern: %s, error: %w", pattern, err) } return nil } @@ -273,7 +273,7 @@ func (connector *DbConnector) RemovePatternsMetrics(patterns []string) error { pipe.Del(connector.context, patternMetricsKey(pattern)) //nolint } if _, err := pipe.Exec(connector.context); err != nil { - return fmt.Errorf("failed to EXEC: %v", err) + return fmt.Errorf("failed to EXEC: %w", err) } return nil } @@ -292,7 +292,7 @@ func (connector *DbConnector) RemovePatternWithMetrics(pattern string) error { } pipe.Del(connector.context, patternMetricsKey(pattern)) if _, err = pipe.Exec(connector.context); err != nil { - return fmt.Errorf("failed to EXEC: %v", err) + return fmt.Errorf("failed to EXEC: %w", err) } return nil } @@ -301,7 +301,7 @@ func (connector *DbConnector) RemovePatternWithMetrics(pattern string) error { func (connector *DbConnector) RemoveMetricRetention(metric string) error { c := *connector.client if _, err := c.Del(connector.context, metricRetentionKey(metric)).Result(); err != nil { - return fmt.Errorf("failed to remove retention, error: %v", err) + return fmt.Errorf("failed to remove retention, error: %w", err) } return nil @@ -315,7 +315,7 @@ func (connector *DbConnector) RemoveMetricValues(metric string, toTime int64) (i c := *connector.client result, err := c.ZRemRangeByScore(connector.context, metricDataKey(metric), "-inf", strconv.FormatInt(toTime, 10)).Result() if err != nil { - return 0, fmt.Errorf("failed to remove metrics from -inf to %v, error: %v", toTime, err) + return 0, fmt.Errorf("failed to remove metrics from -inf to %v, error: %w", toTime, err) } return result, nil @@ -335,7 +335,7 @@ func (connector *DbConnector) RemoveMetricsValues(metrics []string, toTime int64 } } if _, err := pipe.Exec(connector.context); err != nil { - return fmt.Errorf("failed to EXEC remove metrics: %v", err) + return fmt.Errorf("failed to EXEC remove metrics: %w", err) } return nil } @@ -374,7 +374,7 @@ func cleanUpAbandonedRetentionsOnRedisNode(connector *DbConnector, client redis. result, err := (*connector.client).Exists(connector.context, metricDataKey(metric)).Result() if err != nil { - return fmt.Errorf("failed to check metric data existence, error: %v", err) + return fmt.Errorf("failed to check metric data existence, error: %w", err) } if isMetricExists := result == 1; !isMetricExists { err = connector.RemoveMetricRetention(metric) diff --git a/database/redis/metric_test.go b/database/redis/metric_test.go index 665470f8c..7001aa7f7 100644 --- a/database/redis/metric_test.go +++ b/database/redis/metric_test.go @@ -77,7 +77,7 @@ func TestMetricsStoring(t *testing.T) { So(err, ShouldBeNil) }) - Convey("You can remove remove pattern with metrics in one request", func() { + Convey("You can remove pattern with metrics in one request", func() { err = dataBase.RemovePatternWithMetrics(pattern) So(err, ShouldBeNil) }) diff --git a/database/redis/notification.go b/database/redis/notification.go index f22871a95..fb185c5f0 100644 --- a/database/redis/notification.go +++ b/database/redis/notification.go @@ -215,12 +215,12 @@ func (connector *DbConnector) fetchNotificationsWithLimitDo(to int64, limit int6 }, notifierNotificationsKey) if err != nil { - return nil, fmt.Errorf("failed to ZRANGEBYSCORE: %s", err) + return nil, fmt.Errorf("failed to ZRANGEBYSCORE: %w", err) } notifications, err := reply.Notifications(response) if err != nil { - return nil, fmt.Errorf("failed to EXEC: %s", err) + return nil, fmt.Errorf("failed to EXEC: %w", err) } if len(notifications) == 0 { @@ -268,7 +268,7 @@ func (connector *DbConnector) fetchNotificationsNoLimit(to int64) ([]*moira.Sche response, err := pipe.Exec(ctx) if err != nil { - return nil, fmt.Errorf("failed to EXEC: %s", err) + return nil, fmt.Errorf("failed to EXEC: %w", err) } return reply.Notifications(response[0].(*redis.StringSliceCmd)) diff --git a/database/redis/notification_event.go b/database/redis/notification_event.go index 96438b8f8..03f11fb10 100644 --- a/database/redis/notification_event.go +++ b/database/redis/notification_event.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "strconv" "time" @@ -21,7 +22,7 @@ func (connector *DbConnector) GetNotificationEvents(triggerID string, start int6 eventsData, err := reply.Events(c.ZRevRange(ctx, triggerEventsKey(triggerID), start, start+size)) if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]*moira.NotificationEvent, 0), nil } return nil, fmt.Errorf("failed to get range for trigger events, triggerID: %s, error: %s", triggerID, err.Error()) @@ -81,7 +82,7 @@ func (connector *DbConnector) FetchNotificationEvent() (moira.NotificationEvent, response := c.BRPop(ctx, time.Second, notificationEventsList) err := response.Err() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return event, database.ErrNil } @@ -91,7 +92,7 @@ func (connector *DbConnector) FetchNotificationEvent() (moira.NotificationEvent, event, _ = reply.BRPopToEvent(response) - if event.Values == nil { //TODO(litleleprikon): remove in moira v2.8.0. Compatibility with moira < v2.6.0 + if event.Values == nil { // TODO(litleleprikon): remove in moira v2.8.0. Compatibility with moira < v2.6.0 event.Values = make(map[string]float64) } diff --git a/database/redis/reply/check.go b/database/redis/reply/check.go index 72f0c6167..29fbfef70 100644 --- a/database/redis/reply/check.go +++ b/database/redis/reply/check.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -12,8 +13,7 @@ import ( // TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 const firstTarget = "t1" -//TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 - +// TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 type checkDataStorageElement struct { Metrics map[string]moira.MetricState `json:"metrics"` MetricsToTargetRelation map[string]string `json:"metrics_to_target_relation"` @@ -30,7 +30,7 @@ type checkDataStorageElement struct { } func toCheckDataStorageElement(check moira.CheckData) checkDataStorageElement { - //TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 for metricName, metricState := range check.Metrics { if metricState.Value == nil { if value, ok := metricState.Values[firstTarget]; ok { @@ -39,7 +39,7 @@ func toCheckDataStorageElement(check moira.CheckData) checkDataStorageElement { } } } - //TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 return checkDataStorageElement{ Metrics: check.Metrics, MetricsToTargetRelation: check.MetricsToTargetRelation, @@ -57,7 +57,7 @@ func toCheckDataStorageElement(check moira.CheckData) checkDataStorageElement { } func (d checkDataStorageElement) toCheckData() moira.CheckData { - //TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 for metricName, metricState := range d.Metrics { if metricState.Values == nil { metricState.Values = make(map[string]float64) @@ -71,7 +71,7 @@ func (d checkDataStorageElement) toCheckData() moira.CheckData { if d.MetricsToTargetRelation == nil { d.MetricsToTargetRelation = make(map[string]string) } - //TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 return moira.CheckData{ Metrics: d.Metrics, MetricsToTargetRelation: d.MetricsToTargetRelation, @@ -93,7 +93,7 @@ func Check(rep *redis.StringCmd) (moira.CheckData, error) { bytes, err := rep.Bytes() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return moira.CheckData{}, database.ErrNil } diff --git a/database/redis/reply/contact.go b/database/redis/reply/contact.go index b5b9c39e4..246c9c64a 100644 --- a/database/redis/reply/contact.go +++ b/database/redis/reply/contact.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/moira-alert/moira/database" @@ -13,7 +14,7 @@ import ( func unmarshalContact(bytes []byte, err error) (moira.ContactData, error) { contact := moira.ContactData{} if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return contact, database.ErrNil } return contact, fmt.Errorf("failed to read contact: %s", err.Error()) @@ -37,9 +38,10 @@ func Contacts(rep []*redis.StringCmd) ([]*moira.ContactData, error) { contacts := make([]*moira.ContactData, len(rep)) for i, value := range rep { contact, err := unmarshalContact(value.Bytes()) - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return nil, err - } else if err == database.ErrNil { + } + if errors.Is(err, database.ErrNil) { contacts[i] = nil } else { contacts[i] = &contact diff --git a/database/redis/reply/event.go b/database/redis/reply/event.go index d518c6a00..ac6de2bdf 100644 --- a/database/redis/reply/event.go +++ b/database/redis/reply/event.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -25,13 +26,13 @@ type notificationEventStorageElement struct { } func toNotificationEventStorageElement(event moira.NotificationEvent) notificationEventStorageElement { - //TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 if event.Value == nil { if value, ok := event.Values[firstTarget]; ok { event.Value = &value } } - //TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 return notificationEventStorageElement{ IsTriggerEvent: event.IsTriggerEvent, Timestamp: event.Timestamp, @@ -49,7 +50,7 @@ func toNotificationEventStorageElement(event moira.NotificationEvent) notificati } func (e notificationEventStorageElement) toNotificationEvent() moira.NotificationEvent { - //TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 if e.Values == nil { e.Values = make(map[string]float64) } @@ -57,7 +58,7 @@ func (e notificationEventStorageElement) toNotificationEvent() moira.Notificatio e.Values[firstTarget] = *e.Value e.Value = nil } - //TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 return moira.NotificationEvent{ IsTriggerEvent: e.IsTriggerEvent, Timestamp: e.Timestamp, @@ -86,7 +87,7 @@ func GetEventBytes(event moira.NotificationEvent) ([]byte, error) { func unmarshalEvent(data string, err error) (moira.NotificationEvent, error) { if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return moira.NotificationEvent{}, database.ErrNil } return moira.NotificationEvent{}, fmt.Errorf("failed to read event: %s", err.Error()) @@ -113,7 +114,7 @@ func Events(response *redis.StringSliceCmd) ([]*moira.NotificationEvent, error) values, err := response.Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]*moira.NotificationEvent, 0), nil } return nil, fmt.Errorf("failed to read events: %s", err.Error()) @@ -122,9 +123,10 @@ func Events(response *redis.StringSliceCmd) ([]*moira.NotificationEvent, error) events := make([]*moira.NotificationEvent, len(values)) for i, value := range values { event, err2 := unmarshalEvent(value, err) - if err2 != nil && err2 != database.ErrNil { + if err2 != nil && !errors.Is(err2, database.ErrNil) { return nil, err2 - } else if err2 == database.ErrNil { + } + if errors.Is(err2, database.ErrNil) { events[i] = nil } else { events[i] = &event diff --git a/database/redis/reply/metric.go b/database/redis/reply/metric.go index 4a9896864..1a2a55a61 100644 --- a/database/redis/reply/metric.go +++ b/database/redis/reply/metric.go @@ -1,6 +1,7 @@ package reply import ( + "errors" "fmt" "strconv" "strings" @@ -13,7 +14,7 @@ import ( func MetricValues(values *redis.ZSliceCmd) ([]*moira.MetricValue, error) { resultByMetricArr, err := values.Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]*moira.MetricValue, 0), nil } return nil, fmt.Errorf("failed to read metricValues: %s", err.Error()) diff --git a/database/redis/reply/notification.go b/database/redis/reply/notification.go index 399be8f0e..51ab539a8 100644 --- a/database/redis/reply/notification.go +++ b/database/redis/reply/notification.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -57,7 +58,7 @@ func GetNotificationBytes(notification moira.ScheduledNotification) ([]byte, err // unmarshalNotification converts JSON to moira.ScheduledNotification object func unmarshalNotification(bytes []byte, err error) (moira.ScheduledNotification, error) { if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return moira.ScheduledNotification{}, database.ErrNil } return moira.ScheduledNotification{}, fmt.Errorf("failed to read scheduledNotification: %s", err.Error()) @@ -72,7 +73,7 @@ func unmarshalNotification(bytes []byte, err error) (moira.ScheduledNotification // Notifications converts redis DB reply to moira.ScheduledNotification objects array func Notifications(responses *redis.StringSliceCmd) ([]*moira.ScheduledNotification, error) { - if responses == nil || responses.Err() == redis.Nil { + if responses == nil || errors.Is(responses.Err(), redis.Nil) { return make([]*moira.ScheduledNotification, 0), nil } @@ -84,9 +85,10 @@ func Notifications(responses *redis.StringSliceCmd) ([]*moira.ScheduledNotificat notifications := make([]*moira.ScheduledNotification, len(data)) for i, value := range data { notification, err2 := unmarshalNotification([]byte(value), err) - if err2 != nil && err2 != database.ErrNil { + if err2 != nil && !errors.Is(err2, database.ErrNil) { return nil, err2 - } else if err2 == database.ErrNil { + } + if errors.Is(err2, database.ErrNil) { notifications[i] = nil } else { notifications[i] = ¬ification diff --git a/database/redis/reply/search_result.go b/database/redis/reply/search_result.go index 8485a0c56..f4eb7cee8 100644 --- a/database/redis/reply/search_result.go +++ b/database/redis/reply/search_result.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -59,7 +60,7 @@ func unmarshalSearchResult(bytes []byte, err error) (moira.SearchResult, error) storageElement := searchResultStorageElement{} if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return searchResult, database.ErrNil } return searchResult, fmt.Errorf("failed to read searchResult: %w", err) @@ -77,7 +78,7 @@ func SearchResults(rep *redis.StringSliceCmd, repTotal *redis.IntCmd) ([]*moira. total := repTotal.Val() values, err := rep.Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]*moira.SearchResult, 0), 0, nil } return nil, 0, fmt.Errorf("failed to read SearchResults: %w", err) @@ -85,9 +86,10 @@ func SearchResults(rep *redis.StringSliceCmd, repTotal *redis.IntCmd) ([]*moira. searchResults := make([]*moira.SearchResult, len(values)) for i, value := range values { searchResult, err2 := unmarshalSearchResult([]byte(value), err) - if err2 != nil && err2 != database.ErrNil { + if err2 != nil && !errors.Is(err2, database.ErrNil) { return nil, 0, err2 - } else if err2 == database.ErrNil { + } + if errors.Is(err2, database.ErrNil) { searchResults[i] = nil } else { searchResults[i] = &searchResult diff --git a/database/redis/reply/subscription.go b/database/redis/reply/subscription.go index 8fbfc54aa..ae6608baf 100644 --- a/database/redis/reply/subscription.go +++ b/database/redis/reply/subscription.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -17,7 +18,7 @@ func Subscription(rep *redis.StringCmd) (moira.SubscriptionData, error) { } bytes, err := rep.Bytes() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return subscription, database.ErrNil } return subscription, fmt.Errorf("failed to read subscription: %s", err.Error()) diff --git a/database/redis/reply/team.go b/database/redis/reply/team.go index 23e8284bf..17ddbd7e3 100644 --- a/database/redis/reply/team.go +++ b/database/redis/reply/team.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -43,7 +44,7 @@ func MarshallTeam(team moira.Team) ([]byte, error) { func NewTeam(rep *redis.StringCmd) (moira.Team, error) { bytes, err := rep.Bytes() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return moira.Team{}, database.ErrNil } return moira.Team{}, fmt.Errorf("failed to read team: %w", err) diff --git a/database/redis/reply/trigger.go b/database/redis/reply/trigger.go index 268ce3537..14f54ccb3 100644 --- a/database/redis/reply/trigger.go +++ b/database/redis/reply/trigger.go @@ -2,6 +2,7 @@ package reply import ( "encoding/json" + "errors" "fmt" "strconv" @@ -37,7 +38,7 @@ type triggerStorageElement struct { } func (storageElement *triggerStorageElement) toTrigger() moira.Trigger { - //TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): START remove in moira v2.8.0. Compatibility with moira < v2.6.0 if storageElement.AloneMetrics == nil { aloneMetricsLen := len(storageElement.Targets) storageElement.AloneMetrics = make(map[string]bool, aloneMetricsLen) @@ -46,7 +47,7 @@ func (storageElement *triggerStorageElement) toTrigger() moira.Trigger { storageElement.AloneMetrics[targetName] = true } } - //TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 + // TODO(litleleprikon): END remove in moira v2.8.0. Compatibility with moira < v2.6.0 triggerSource := storageElement.TriggerSource.FillInIfNotSet(storageElement.IsRemote) return moira.Trigger{ @@ -117,7 +118,7 @@ func getTriggerTTLString(ttl int64) string { func Trigger(rep *redis.StringCmd) (moira.Trigger, error) { bytes, err := rep.Bytes() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return moira.Trigger{}, database.ErrNil } return moira.Trigger{}, fmt.Errorf("failed to read trigger: %s", err.Error()) diff --git a/database/redis/selfstate.go b/database/redis/selfstate.go index 1b6ebf1e6..bea8f1fbc 100644 --- a/database/redis/selfstate.go +++ b/database/redis/selfstate.go @@ -1,6 +1,8 @@ package redis import ( + "errors" + "github.com/go-redis/redis/v8" "github.com/moira-alert/moira" ) @@ -16,7 +18,7 @@ func (connector *DbConnector) UpdateMetricsHeartbeat() error { func (connector *DbConnector) GetMetricsUpdatesCount() (int64, error) { c := *connector.client ts, err := c.Get(connector.context, selfStateMetricsHeartbeatKey).Int64() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return 0, nil } return ts, err @@ -26,7 +28,7 @@ func (connector *DbConnector) GetMetricsUpdatesCount() (int64, error) { func (connector *DbConnector) GetChecksUpdatesCount() (int64, error) { c := *connector.client ts, err := c.Get(connector.context, selfStateChecksCounterKey).Int64() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return 0, nil } return ts, err @@ -36,17 +38,17 @@ func (connector *DbConnector) GetChecksUpdatesCount() (int64, error) { func (connector *DbConnector) GetRemoteChecksUpdatesCount() (int64, error) { c := *connector.client ts, err := c.Get(connector.context, selfStateRemoteChecksCounterKey).Int64() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return 0, nil } return ts, err } -// GetRemoteChecksUpdatesCount return remote checks count by Moira-Checker +// GetPrometheusChecksUpdatesCount return remote checks count by Moira-Checker func (connector *DbConnector) GetPrometheusChecksUpdatesCount() (int64, error) { c := *connector.client ts, err := c.Get(connector.context, selfStatePrometheusChecksCounterKey).Int64() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return 0, nil } return ts, err @@ -56,7 +58,7 @@ func (connector *DbConnector) GetPrometheusChecksUpdatesCount() (int64, error) { func (connector *DbConnector) GetNotifierState() (string, error) { c := *connector.client ts, err := c.Get(connector.context, selfStateNotifierHealth).Result() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { ts = moira.SelfStateOK err = connector.SetNotifierState(ts) } else if err != nil { diff --git a/database/redis/subscription.go b/database/redis/subscription.go index 88f2f297d..3fc3e4bf4 100644 --- a/database/redis/subscription.go +++ b/database/redis/subscription.go @@ -3,6 +3,7 @@ package redis import ( "context" "encoding/json" + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -41,7 +42,7 @@ func (connector *DbConnector) GetSubscriptions(subscriptionIDs []string) ([]*moi } _, err := pipe.Exec(connector.context) - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return nil, fmt.Errorf("failed to EXEC: %s", err.Error()) } for i, result := range results { @@ -68,7 +69,7 @@ func (connector *DbConnector) SaveSubscription(subscription *moira.SubscriptionD if subscription, err := connector.GetSubscription(subscription.ID); err == nil { oldSubscription = &subscription - } else if err != database.ErrNil { + } else if !errors.Is(err, database.ErrNil) { return err } oldTriggers, err := connector.getSubscriptionTriggers(oldSubscription) @@ -142,7 +143,7 @@ func (connector *DbConnector) updateSubscriptions(oldSubscriptions []*moira.Subs func (connector *DbConnector) RemoveSubscription(subscriptionID string) error { subscription, err := connector.GetSubscription(subscriptionID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return nil } return err diff --git a/database/redis/tag.go b/database/redis/tag.go index d1bff737a..3a39469a5 100644 --- a/database/redis/tag.go +++ b/database/redis/tag.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -36,7 +37,7 @@ func (connector *DbConnector) GetTagTriggerIDs(tagName string) ([]string, error) triggerIDs, err := c.SMembers(connector.context, tagTriggersKey(tagName)).Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]string, 0), nil } return nil, fmt.Errorf("failed to retrieve tag triggers:%s, err: %s", tagName, err.Error()) @@ -56,7 +57,7 @@ func (connector *DbConnector) CleanUpAbandonedTags() (int, error) { result, err := client.Exists(connector.context, tagTriggersKey(tag)).Result() if err != nil { - return count, fmt.Errorf("failed to check tag triggers existence, error: %v", err) + return count, fmt.Errorf("failed to check tag triggers existence, error: %w", err) } if isTriggerExists := result == 1; isTriggerExists { continue @@ -64,7 +65,7 @@ func (connector *DbConnector) CleanUpAbandonedTags() (int, error) { result, err = client.Exists(connector.context, tagSubscriptionKey(tag)).Result() if err != nil { - return count, fmt.Errorf("failed to check tag subscription existence, error: %v", err) + return count, fmt.Errorf("failed to check tag subscription existence, error: %w", err) } if isSubscriptionExists := result == 1; isSubscriptionExists { continue diff --git a/database/redis/trigger.go b/database/redis/trigger.go index b8868dbdd..c48213eb8 100644 --- a/database/redis/trigger.go +++ b/database/redis/trigger.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "strconv" "strings" @@ -91,7 +92,7 @@ func (connector *DbConnector) GetTrigger(triggerID string) (moira.Trigger, error triggerTags := pipe.SMembers(connector.context, triggerTagsKey(triggerID)) _, err := pipe.Exec(connector.context) if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return moira.Trigger{}, database.ErrNil } return moira.Trigger{}, fmt.Errorf("failed to EXEC: %s", err.Error()) @@ -109,7 +110,7 @@ func (connector *DbConnector) GetTriggers(triggerIDs []string) ([]*moira.Trigger pipe.SMembers(connector.context, triggerTagsKey(triggerID)) } rawResponse, err := pipe.Exec(connector.context) - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return nil, fmt.Errorf("failed to EXEC: %s", err.Error()) } @@ -119,7 +120,7 @@ func (connector *DbConnector) GetTriggers(triggerIDs []string) ([]*moira.Trigger triggerCmd, tagCmd := rawResponse[i].(*redis.StringCmd), rawResponse[i+1].(*redis.StringSliceCmd) trigger, err := connector.getTriggerWithTags(triggerCmd, tagCmd, triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { continue } return nil, err @@ -145,7 +146,7 @@ func (connector *DbConnector) RemovePatternTriggerIDs(pattern string) error { c := *connector.client _, err := c.Del(connector.context, patternTriggersKey(pattern)).Result() if err != nil { - return fmt.Errorf("failed delete pattern-triggers: %s, error: %s", pattern, err) + return fmt.Errorf("failed delete pattern-triggers: %s, error: %w", pattern, err) } return nil } @@ -159,7 +160,7 @@ func (connector *DbConnector) SaveTrigger(triggerID string, trigger *moira.Trigg var oldTrigger *moira.Trigger if existing, err := connector.GetTrigger(triggerID); err == nil { oldTrigger = &existing - } else if err != database.ErrNil { + } else if !errors.Is(err, database.ErrNil) { return fmt.Errorf("failed to get trigger: %s", err.Error()) } @@ -288,7 +289,7 @@ func (connector *DbConnector) preSaveTrigger(newTrigger *moira.Trigger, oldTrigg func (connector *DbConnector) RemoveTrigger(triggerID string) error { trigger, err := connector.GetTrigger(triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { return nil } return err @@ -347,8 +348,8 @@ func (connector *DbConnector) GetTriggerChecks(triggerIDs []string) ([]*moira.Tr } rawResponse, err := pipe.Exec(connector.context) - if err != nil && err != redis.Nil { - return nil, fmt.Errorf("failed to EXEC: %s", err) + if err != nil && !errors.Is(err, redis.Nil) { + return nil, fmt.Errorf("failed to EXEC: %w", err) } var slices [][]interface{} for i := 0; i < len(rawResponse); i += 4 { @@ -363,13 +364,13 @@ func (connector *DbConnector) GetTriggerChecks(triggerIDs []string) ([]*moira.Tr triggerCmd, tagCmd := slice[1].(*redis.StringCmd), slice[2].(*redis.StringSliceCmd) trigger, err := connector.getTriggerWithTags(triggerCmd, tagCmd, triggerID) if err != nil { - if err == database.ErrNil { + if errors.Is(err, database.ErrNil) { continue } return nil, err } lastCheck, err := reply.Check(slice[3].(*redis.StringCmd)) - if err != nil && err != database.ErrNil { + if err != nil && !errors.Is(err, database.ErrNil) { return nil, err } throttlingStr, _ := slice[4].(*redis.StringCmd).Result() diff --git a/database/redis/trigger_test.go b/database/redis/trigger_test.go index ffabae0fc..c68ecb8f4 100644 --- a/database/redis/trigger_test.go +++ b/database/redis/trigger_test.go @@ -850,7 +850,7 @@ var testTriggers = []moira.Trigger{ TriggerType: moira.RisingTrigger, TTLState: &moira.TTLStateNODATA, AloneMetrics: map[string]bool{}, - //TODO: Test that empty TriggerSource is filled on getting vale from db + // TODO: Test that empty TriggerSource is filled on getting vale from db TriggerSource: moira.GraphiteLocal, }, { diff --git a/database/redis/triggers_lock.go b/database/redis/triggers_lock.go index 3f54995fe..0ee3521af 100644 --- a/database/redis/triggers_lock.go +++ b/database/redis/triggers_lock.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "time" @@ -33,7 +34,7 @@ func (connector *DbConnector) SetTriggerCheckLock(triggerID string) (bool, error c := *connector.client err := c.SetArgs(connector.context, metricCheckLockKey(triggerID), time.Now().Unix(), redis.SetArgs{TTL: 30 * time.Second, Mode: "NX"}).Err() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return false, nil } return false, fmt.Errorf("failed to set check lock: %s error: %s", triggerID, err.Error()) diff --git a/database/redis/triggers_to_check.go b/database/redis/triggers_to_check.go index 0281d9453..cbb7f5d30 100644 --- a/database/redis/triggers_to_check.go +++ b/database/redis/triggers_to_check.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -70,7 +71,7 @@ func (connector *DbConnector) getTriggersToCheck(key string, count int) ([]strin triggerIDs, err := c.SPopN(ctx, key, int64(count)).Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]string, 0), database.ErrNil } return make([]string, 0), fmt.Errorf("failed to pop trigger to check: %s", err.Error()) @@ -84,7 +85,7 @@ func (connector *DbConnector) getTriggersToCheckCount(key string) (int64, error) triggersToCheckCount, err := c.SCard(ctx, key).Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return 0, nil } return 0, fmt.Errorf("failed to get trigger to check count: %s", err.Error()) diff --git a/database/redis/triggers_to_reindex.go b/database/redis/triggers_to_reindex.go index 1f173b0e8..8acd9de4a 100644 --- a/database/redis/triggers_to_reindex.go +++ b/database/redis/triggers_to_reindex.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "strconv" @@ -33,7 +34,7 @@ func (connector *DbConnector) RemoveTriggersToReindex(to int64) error { _, err := c.ZRemRangeByScore(ctx, triggersToReindexKey, "-inf", strconv.FormatInt(to, 10)).Result() - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return fmt.Errorf("failed to remove triggers to reindex: %s", err.Error()) } diff --git a/database/redis/unused_triggers.go b/database/redis/unused_triggers.go index 2ec7c55ba..07ee707f5 100644 --- a/database/redis/unused_triggers.go +++ b/database/redis/unused_triggers.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "fmt" "github.com/go-redis/redis/v8" @@ -33,7 +34,7 @@ func (connector *DbConnector) GetUnusedTriggerIDs() ([]string, error) { triggerIds, err := c.SMembers(ctx, unusedTriggersKey).Result() if err != nil { - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return make([]string, 0), nil } return nil, fmt.Errorf("failed to get all unused triggers: %s", err.Error()) diff --git a/expression/expression.go b/expression/expression.go index 690a4c486..32b162176 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -124,6 +124,7 @@ func getSimpleExpression(triggerExpression *TriggerExpression) (*govaluate.Evalu if triggerExpression.ErrorValue == nil && triggerExpression.WarnValue == nil { return nil, fmt.Errorf("error value and warning value can not be empty") } + switch triggerExpression.TriggerType { case "": return nil, fmt.Errorf("trigger_type is not set") @@ -143,9 +144,10 @@ func getSimpleExpression(triggerExpression *TriggerExpression) (*govaluate.Evalu } else { return exprWarnRising, nil } + default: + return nil, fmt.Errorf("wrong set of parametres: warn_value - %v, error_value - %v, trigger_type: %v", + triggerExpression.WarnValue, triggerExpression.ErrorValue, triggerExpression.TriggerType) } - return nil, fmt.Errorf("wrong set of parametres: warn_value - %v, error_value - %v, trigger_type: %v", - triggerExpression.WarnValue, triggerExpression.ErrorValue, triggerExpression.TriggerType) } func getUserExpression(triggerExpression string) (*govaluate.EvaluableExpression, error) { diff --git a/filter/connection/listening.go b/filter/connection/listening.go index b82946b4e..19e5d5910 100644 --- a/filter/connection/listening.go +++ b/filter/connection/listening.go @@ -1,6 +1,7 @@ package connection import ( + "errors" "fmt" "net" "time" @@ -60,7 +61,8 @@ func (listener *MetricsListener) Listen() chan []byte { listener.listener.SetDeadline(time.Now().Add(1e9)) //nolint conn, err := listener.listener.Accept() if nil != err { - if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { + var opErr *net.OpError + if ok := errors.Is(err, opErr); ok && opErr.Timeout() { continue } listener.logger.Info(). diff --git a/filter/metrics_parser.go b/filter/metrics_parser.go index f68eb36fe..95ca51fd7 100644 --- a/filter/metrics_parser.go +++ b/filter/metrics_parser.go @@ -46,17 +46,17 @@ func ParseMetric(input []byte) (*ParsedMetric, error) { name, labels, err := parseNameAndLabels(metricBytes) if err != nil { - return nil, fmt.Errorf("cannot parse metric: '%s' (%s)", input, err) + return nil, fmt.Errorf("cannot parse metric: '%s' (%w)", input, err) } value, err := parseFloat(valueBytes) if err != nil { - return nil, fmt.Errorf("cannot parse value: '%s' (%s)", input, err) + return nil, fmt.Errorf("cannot parse value: '%s' (%w)", input, err) } timestamp, err := parseFloat(timestampBytes) if err != nil { - return nil, fmt.Errorf("cannot parse timestamp: '%s' (%s)", input, err) + return nil, fmt.Errorf("cannot parse timestamp: '%s' (%w)", input, err) } parsedMetric := &ParsedMetric{ diff --git a/filter/patterns_storage.go b/filter/patterns_storage.go index a23e5e511..ee1962c92 100644 --- a/filter/patterns_storage.go +++ b/filter/patterns_storage.go @@ -1,6 +1,7 @@ package filter import ( + "errors" "fmt" "sync/atomic" "time" @@ -51,7 +52,7 @@ func (storage *PatternStorage) Refresh() error { patterns := make([]string, 0) for _, newPattern := range newPatterns { tagSpecs, err := ParseSeriesByTag(newPattern) - if err == ErrNotSeriesByTag { + if errors.Is(err, ErrNotSeriesByTag) { patterns = append(patterns, newPattern) } else { seriesByTagPatterns[newPattern] = tagSpecs diff --git a/image_store/s3/init.go b/image_store/s3/init.go index 785e1378e..9319bc325 100644 --- a/image_store/s3/init.go +++ b/image_store/s3/init.go @@ -43,7 +43,7 @@ func (imageStore *ImageStore) Init(config Config) error { var err error imageStore.sess, err = session.NewSession(awsconfig) if err != nil { - return fmt.Errorf("could not configure s3 session: %s", err) + return fmt.Errorf("could not configure s3 session: %w", err) } imageStore.uploader = s3manager.NewUploader(imageStore.sess) diff --git a/image_store/s3/store.go b/image_store/s3/store.go index e26ce2962..81dc1e682 100644 --- a/image_store/s3/store.go +++ b/image_store/s3/store.go @@ -14,11 +14,11 @@ import ( func (imageStore *ImageStore) StoreImage(image []byte) (string, error) { uploadInput, err := imageStore.buildUploadInput(image) if err != nil { - return "", fmt.Errorf("error while creating upload input: %s", err) + return "", fmt.Errorf("error while creating upload input: %w", err) } result, err := imageStore.uploader.Upload(uploadInput) if err != nil { - return "", fmt.Errorf("error while uploading to s3: %s", err) + return "", fmt.Errorf("error while uploading to s3: %w", err) } return result.Location, nil @@ -27,7 +27,7 @@ func (imageStore *ImageStore) StoreImage(image []byte) (string, error) { func (imageStore *ImageStore) buildUploadInput(image []byte) (*s3manager.UploadInput, error) { uuid, err := uuid.NewV4() if err != nil { - return nil, fmt.Errorf("failed to generate uuid: %s", err) + return nil, fmt.Errorf("failed to generate uuid: %w", err) } key := "moira-plots/" + uuid.String() return &s3manager.UploadInput{ diff --git a/index/index_test.go b/index/index_test.go index 038d56398..7d654df92 100644 --- a/index/index_test.go +++ b/index/index_test.go @@ -47,7 +47,7 @@ func TestGetTriggerChecksWithRetries(t *testing.T) { dataBase.EXPECT().GetTriggerChecks(randomBatch).Return(nil, expectedError).Times(3) actualData, actualError := index.getTriggerChecksWithRetries(randomBatch) So(actualData, ShouldBeEmpty) - So(actualError, ShouldResemble, fmt.Errorf("cannot get trigger checks from DB after 3 tries, last error: %s", expectedError)) + So(actualError, ShouldResemble, fmt.Errorf("cannot get trigger checks from DB after 3 tries, last error: %w", expectedError)) }) } diff --git a/index/mapping/trigger_test.go b/index/mapping/trigger_test.go index 3cc0b0c2f..7fd9148dc 100644 --- a/index/mapping/trigger_test.go +++ b/index/mapping/trigger_test.go @@ -49,7 +49,7 @@ func getTagByFieldName(fieldName string) string { var fieldTag string if field, ok := reflect.TypeOf(&trigger).Elem().FieldByName(fieldName); ok { fieldTag = field.Tag.Get("json") - fieldTag = strings.Replace(fieldTag, ",omitempty", "", -1) + fieldTag = strings.ReplaceAll(fieldTag, ",omitempty", "") } return fieldTag } diff --git a/metric_source/local/errors.go b/metric_source/local/errors.go index 82d5e11e8..2ef627e7d 100644 --- a/metric_source/local/errors.go +++ b/metric_source/local/errors.go @@ -17,7 +17,7 @@ type ErrUnknownFunction struct { // ErrorUnknownFunction parses internal carbon-api error errUnknownFunction, gets func name and return ErrUnknownFunction error func ErrorUnknownFunction(err error) ErrUnknownFunction { errorStr := err.Error() - funcName := strings.Replace(errorStr[strings.Index(errorStr, "\""):], "\"", "", -1) + funcName := strings.ReplaceAll(errorStr[strings.Index(errorStr, "\""):], "\"", "") return ErrUnknownFunction{ internalError: err, FuncName: funcName, @@ -34,7 +34,7 @@ func (err ErrUnknownFunction) Error() string { // isErrUnknownFunction checks error for carbonapi.errUnknownFunction func isErrUnknownFunction(err error) bool { - switch merry.Unwrap(err).(type) { + switch merry.Unwrap(err).(type) { // nolint:errorlint case helper.ErrUnknownFunction: return true } diff --git a/metric_source/local/eval.go b/metric_source/local/eval.go index a2d51a6ae..3d36c9e2a 100644 --- a/metric_source/local/eval.go +++ b/metric_source/local/eval.go @@ -148,7 +148,7 @@ func (ctx *evalCtx) rewriteExpr(parsedExpr parser.Expr, metrics *fetchedMetrics) metrics.metricsMap, ) - if err != nil && err != parser.ErrMissingTimeseries { + if err != nil && !errors.Is(err, parser.ErrMissingTimeseries) { return false, nil, fmt.Errorf("failed RewriteExpr: %s", err.Error()) } return rewritten, newTargets, nil diff --git a/metric_source/remote/request.go b/metric_source/remote/request.go index a6148954e..686b1766b 100644 --- a/metric_source/remote/request.go +++ b/metric_source/remote/request.go @@ -1,6 +1,7 @@ package remote import ( + "context" "fmt" "io" "net/http" @@ -8,7 +9,7 @@ import ( ) func (remote *Remote) prepareRequest(from, until int64, target string) (*http.Request, error) { - req, err := http.NewRequest("GET", remote.config.URL, nil) + req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, remote.config.URL, nil) if err != nil { return nil, err } diff --git a/metrics/graphite.go b/metrics/graphite.go index 37bc4fbaf..0dda00431 100644 --- a/metrics/graphite.go +++ b/metrics/graphite.go @@ -70,7 +70,7 @@ func initPrefix(prefix string) (string, error) { return prefix, err } short := strings.Split(hostname, ".")[0] - return strings.Replace(prefix, hostnameTmpl, short, -1), nil + return strings.ReplaceAll(prefix, hostnameTmpl, short), nil } type graphiteCounter struct { diff --git a/notifier/events/event.go b/notifier/events/event.go index 32b72bb84..f854b7187 100644 --- a/notifier/events/event.go +++ b/notifier/events/event.go @@ -1,6 +1,7 @@ package events import ( + "errors" "fmt" "time" @@ -37,7 +38,7 @@ func (worker *FetchEventsWorker) Start() { { event, err := worker.Database.FetchNotificationEvent() if err != nil { - if err != database.ErrNil { + if !errors.Is(err, database.ErrNil) { worker.Metrics.EventsMalformed.Mark(1) worker.Logger.Warning(). Error(err). diff --git a/notifier/notifications/notifications.go b/notifier/notifications/notifications.go index e7cd5be9d..a9e77e48b 100644 --- a/notifier/notifications/notifications.go +++ b/notifier/notifications/notifications.go @@ -44,7 +44,7 @@ func (worker *FetchNotificationsWorker) Start() { return nil case <-checkTicker.C: if err := worker.processScheduledNotifications(); err != nil { - switch err.(type) { + switch err.(type) { // nolint:errorlint case notifierInBadStateError: worker.Logger.Warning(). String("stop_sending_notifications_for", sleepAfterNotifierBadState.String()). diff --git a/notifier/notifier.go b/notifier/notifier.go index 9ae11751c..794cbcd78 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -188,7 +188,7 @@ func (notifier *StandardNotifier) runSender(sender moira.Sender, ch chan Notific plots, err := notifier.buildNotificationPackagePlots(pkg, plottingLog) if err != nil { var event logging.EventBuilder - switch err.(type) { + switch err.(type) { // nolint:errorlint case plotting.ErrNoPointsToRender: event = plottingLog.Debug() default: @@ -212,7 +212,7 @@ func (notifier *StandardNotifier) runSender(sender moira.Sender, ch chan Notific notifier.metrics.MarkSendersOkMetrics(pkg.Contact.Type) continue } - switch e := err.(type) { + switch e := err.(type) { // nolint:errorlint case moira.SenderBrokenContactError: log.Warning(). Error(e). diff --git a/notifier/plotting.go b/notifier/plotting.go index e917b1276..9992898f5 100644 --- a/notifier/plotting.go +++ b/notifier/plotting.go @@ -2,6 +2,7 @@ package notifier import ( "bytes" + "errors" "fmt" "time" @@ -167,7 +168,8 @@ func fetchAvailableSeries(metricsSource metricSource.MetricSource, target string if realtimeErr == nil { return realtimeFetchResult.GetMetricsData(), nil } - if errFailedWithPanic, ok := realtimeErr.(local.ErrEvaluateTargetFailedWithPanic); ok { + var errFailedWithPanic local.ErrEvaluateTargetFailedWithPanic + if ok := errors.Is(realtimeErr, errFailedWithPanic); ok { fetchResult, err := metricsSource.Fetch(target, from, to, false) if err != nil { return nil, errFetchAvailableSeriesFailed{realtimeErr: errFailedWithPanic.Error(), storedErr: err.Error()} diff --git a/notifier/registrator.go b/notifier/registrator.go index e31f6e7b1..6f9d88bb9 100644 --- a/notifier/registrator.go +++ b/notifier/registrator.go @@ -150,5 +150,5 @@ func (notifier *StandardNotifier) StopSenders() { } func getGraphiteSenderIdent(ident string) string { - return strings.Replace(ident, " ", "_", -1) + return strings.ReplaceAll(ident, " ", "_") } diff --git a/notifier/scheduler.go b/notifier/scheduler.go index 6456f6e69..d976426bf 100644 --- a/notifier/scheduler.go +++ b/notifier/scheduler.go @@ -152,7 +152,7 @@ func calculateNextDelivery(schedule *moira.ScheduleData, nextTime time.Time) (ti beginOffset := time.Duration(schedule.StartOffset) * time.Minute endOffset := time.Duration(schedule.EndOffset) * time.Minute if schedule.EndOffset < schedule.StartOffset { - endOffset = endOffset + (time.Hour * 24) + endOffset += time.Hour * 24 } tzOffset := time.Duration(schedule.TimezoneOffset) * time.Minute diff --git a/notifier/selfstate/heartbeat/filter_test.go b/notifier/selfstate/heartbeat/filter_test.go index 1db6a7b5e..e8323b827 100644 --- a/notifier/selfstate/heartbeat/filter_test.go +++ b/notifier/selfstate/heartbeat/filter_test.go @@ -78,7 +78,7 @@ func TestFilter(t *testing.T) { }) Convey("Test NeedToCheckOthers and NeedTurnOffNotifier", func() { - //TODO(litleleprikon): seems that this test checks nothing. Seems that NeedToCheckOthers and NeedTurnOffNotifier do not work. + // TODO(litleleprikon): seems that this test checks nothing. Seems that NeedToCheckOthers and NeedTurnOffNotifier do not work. So(check.NeedToCheckOthers(), ShouldBeTrue) So(check.NeedTurnOffNotifier(), ShouldBeFalse) diff --git a/notifier/selfstate/heartbeat/local_checker_test.go b/notifier/selfstate/heartbeat/local_checker_test.go index ae20bcd47..54e224ea3 100644 --- a/notifier/selfstate/heartbeat/local_checker_test.go +++ b/notifier/selfstate/heartbeat/local_checker_test.go @@ -69,7 +69,7 @@ func TestCheckDelay_Check(t *testing.T) { }) Convey("Test NeedToCheckOthers and NeedTurnOffNotifier", func() { - //TODO(litleleprikon): seems that this test checks nothing. Seems that NeedToCheckOthers and NeedTurnOffNotifier do not work. + // TODO(litleleprikon): seems that this test checks nothing. Seems that NeedToCheckOthers and NeedTurnOffNotifier do not work. needCheck := check.NeedToCheckOthers() So(needCheck, ShouldBeTrue) diff --git a/notifier/selfstate/heartbeat/remote_checker_test.go b/notifier/selfstate/heartbeat/remote_checker_test.go index 60181622f..93dfc4ef9 100644 --- a/notifier/selfstate/heartbeat/remote_checker_test.go +++ b/notifier/selfstate/heartbeat/remote_checker_test.go @@ -70,7 +70,7 @@ func TestGraphiteRemoteChecker(t *testing.T) { }) Convey("Test NeedToCheckOthers and NeedTurnOffNotifier", func() { - //TODO(litleleprikon): seems that this test checks nothing. Seems that NeedToCheckOthers and NeedTurnOffNotifier do not work. + // TODO(litleleprikon): seems that this test checks nothing. Seems that NeedToCheckOthers and NeedTurnOffNotifier do not work. So(check.NeedToCheckOthers(), ShouldBeTrue) So(check.NeedTurnOffNotifier(), ShouldBeFalse) }) diff --git a/perfomance_tests/filter/filter_plain_metrics_test.go b/perfomance_tests/filter/filter_plain_metrics_test.go index 775844b63..f3703a0e7 100644 --- a/perfomance_tests/filter/filter_plain_metrics_test.go +++ b/perfomance_tests/filter/filter_plain_metrics_test.go @@ -43,7 +43,7 @@ func generateMetrics(patternStorage *filter.PatternStorage, count int) *[]string if !matched && rand.Float64() < 0.2+level { part = RandStringBytes(len(part)) } - parts = append(parts, strings.Replace(part, "*", "XXXXXXXXX", -1)) + parts = append(parts, strings.ReplaceAll(part, "*", "XXXXXXXXX")) if len(node.Children) == 0 { break } diff --git a/plotting/curve.go b/plotting/curve.go index c86531708..48f5b8f8f 100644 --- a/plotting/curve.go +++ b/plotting/curve.go @@ -64,11 +64,9 @@ func describePlotCurves(metricData metricSource.MetricData) []plotCurve { timeStampValue := moira.Int64ToTime(timeStamp) curves[curvesInd].timeStamps = append(curves[curvesInd].timeStamps, timeStampValue) curves[curvesInd].values = append(curves[curvesInd].values, pointValue) - } else { - if len(curves[curvesInd].values) > 0 { - curves = append(curves, plotCurve{}) - curvesInd++ - } + } else if len(curves[curvesInd].values) > 0 { + curves = append(curves, plotCurve{}) + curvesInd++ } timeStamp += metricData.StepTime } diff --git a/plotting/fonts/ttftogofile/ttf2gofile.go b/plotting/fonts/ttftogofile/ttf2gofile.go index 90b4930f4..d7fffa864 100644 --- a/plotting/fonts/ttftogofile/ttf2gofile.go +++ b/plotting/fonts/ttftogofile/ttf2gofile.go @@ -43,6 +43,7 @@ func main() { usage() os.Exit(1) } + file := os.Args[1] fmt.Println(file[len(file)-5:]) diff --git a/plotting/limits.go b/plotting/limits.go index c1f975f25..b8edb8eb1 100644 --- a/plotting/limits.go +++ b/plotting/limits.go @@ -43,15 +43,15 @@ func resolveLimits(metricsData []metricSource.MetricData) plotLimits { from, to := util.Time.StartAndEnd(allTimes...) lowest, highest := util.Math.MinAndMax(allValues...) if highest == lowest { - highest = highest + (defaultRangeDelta / 2) - lowest = lowest - (defaultRangeDelta / 2) + highest += defaultRangeDelta / 2 + lowest -= defaultRangeDelta / 2 } yAxisIncrement := percentsOfRange(lowest, highest, defaultYAxisRangePercent) if highest > 0 { - highest = highest + yAxisIncrement + highest += yAxisIncrement } if lowest < 0 { - lowest = lowest - yAxisIncrement + lowest -= yAxisIncrement } return plotLimits{ from: from, diff --git a/plotting/plot_test.go b/plotting/plot_test.go index 440561c65..132edaee0 100644 --- a/plotting/plot_test.go +++ b/plotting/plot_test.go @@ -588,14 +588,14 @@ func TestGetRenderable(t *testing.T) { if testCase.errorValue != nil { errorValue := testCase.errorValue.(float64) if !testCase.useHumanizedValues { - errorValue = errorValue * plotTestOuterPointMultiplier + errorValue *= plotTestOuterPointMultiplier } trigger.ErrorValue = &errorValue } if testCase.warnValue != nil { warnValue := testCase.warnValue.(float64) if !testCase.useHumanizedValues { - warnValue = warnValue * plotTestOuterPointMultiplier + warnValue *= plotTestOuterPointMultiplier } trigger.WarnValue = &warnValue } diff --git a/plotting/threshold.go b/plotting/threshold.go index 3af3dfbc9..9e04cd333 100644 --- a/plotting/threshold.go +++ b/plotting/threshold.go @@ -45,7 +45,7 @@ func getThresholdSeriesList(trigger *moira.Trigger, theme moira.PlotTheme, limit for _, plotThreshold := range plotThresholds { thresholdSeriesList = append(thresholdSeriesList, plotThreshold.generateThresholdSeries(theme, limits)) // TODO: uncomment to use annotations if necessary, remove otherwise - //thresholdSeriesList = append(thresholdSeriesList, plotThreshold.generateAnnotationSeries(theme, limits)) + // thresholdSeriesList = append(thresholdSeriesList, plotThreshold.generateAnnotationSeries(theme, limits)) } return thresholdSeriesList } @@ -67,29 +67,31 @@ func generateThresholds(trigger *moira.Trigger, limits plotLimits) []*threshold thresholds = append(thresholds, newThreshold( trigger.TriggerType, "WARN", *trigger.WarnValue, limits.highest)) } - //// Trigger has ERROR value and threshold can be drawn - //errThresholdRequied := trigger.ErrorValue != nil && limits.formsSetContaining(*trigger.ErrorValue) - //if errThresholdRequied { - // thresholds = append(thresholds, newThreshold( - // trigger.TriggerType, "ERROR", *trigger.ErrorValue, limits.highest)) - //} - //// Trigger has WARN value and threshold can be drawn when: - //warnThresholdRequired := trigger.WarnValue != nil && limits.formsSetContaining(*trigger.WarnValue) - //if warnThresholdRequired { - // if errThresholdRequied { - // deltaLimits := math.Abs(limits.highest - limits.lowest) - // deltaThresholds := math.Abs(*trigger.ErrorValue - *trigger.WarnValue) - // if deltaThresholds > thresholdGapCoefficient*deltaLimits { - // //// there is enough place to draw both of ERROR and WARN thresholds - // thresholds = append(thresholds, newThreshold( - // trigger.TriggerType, "WARN", *trigger.WarnValue, limits.highest)) - // } - // } else { - // //// there is no ERROR threshold required - // thresholds = append(thresholds, newThreshold( - // trigger.TriggerType, "WARN", *trigger.WarnValue, limits.highest)) - // } - //} + /** + // Trigger has ERROR value and threshold can be drawn + errThresholdRequied := trigger.ErrorValue != nil && limits.formsSetContaining(*trigger.ErrorValue) + if errThresholdRequied { + thresholds = append(thresholds, newThreshold( + trigger.TriggerType, "ERROR", *trigger.ErrorValue, limits.highest)) + } + // Trigger has WARN value and threshold can be drawn when: + warnThresholdRequired := trigger.WarnValue != nil && limits.formsSetContaining(*trigger.WarnValue) + if warnThresholdRequired { + if errThresholdRequied { + deltaLimits := math.Abs(limits.highest - limits.lowest) + deltaThresholds := math.Abs(*trigger.ErrorValue - *trigger.WarnValue) + if deltaThresholds > thresholdGapCoefficient*deltaLimits { + //// there is enough place to draw both of ERROR and WARN thresholds + thresholds = append(thresholds, newThreshold( + trigger.TriggerType, "WARN", *trigger.WarnValue, limits.highest)) + } + } else { + //// there is no ERROR threshold required + thresholds = append(thresholds, newThreshold( + trigger.TriggerType, "WARN", *trigger.WarnValue, limits.highest)) + } + } + */ return thresholds } @@ -107,17 +109,19 @@ func (threshold *threshold) generateThresholdSeries(theme moira.PlotTheme, limit return thresholdSeries } -//// generateAnnotationSeries returns threshold annotation series -//func (threshold *threshold) generateAnnotationSeries(theme moira.PlotTheme, limits plotLimits) chart.AnnotationSeries { -// annotationSeries := chart.AnnotationSeries{ -// Annotations: []chart.Value2{ -// { -// Label: threshold.thresholdType, -// XValue: float64(limits.to.UnixNano()), -// YValue: threshold.yCoordinate, -// Style: theme.GetAnnotationStyle(threshold.thresholdType), -// }, -// }, -// } -// return annotationSeries -//} +/** +// generateAnnotationSeries returns threshold annotation series +func (threshold *threshold) generateAnnotationSeries(theme moira.PlotTheme, limits plotLimits) chart.AnnotationSeries { + annotationSeries := chart.AnnotationSeries{ + Annotations: []chart.Value2{ + { + Label: threshold.thresholdType, + XValue: float64(limits.to.UnixNano()), + YValue: threshold.yCoordinate, + Style: theme.GetAnnotationStyle(threshold.thresholdType), + }, + }, + } + return annotationSeries +} +*/ diff --git a/plotting/threshold_test.go b/plotting/threshold_test.go index bfeed2175..f07532802 100644 --- a/plotting/threshold_test.go +++ b/plotting/threshold_test.go @@ -11,7 +11,7 @@ import ( ) const ( - //thresholdTestValueIncrement = float64(10) + // thresholdTestValueIncrement = float64(10) thresholdNegativeTestRisingWarnValue = float64(-100) thresholdNegativeTestRisingErrorValue = float64(0) thresholdNegativeTestFallingWarnValue = thresholdNegativeTestRisingErrorValue diff --git a/senders/discord/init.go b/senders/discord/init.go index 6461c1761..ffae43072 100644 --- a/senders/discord/init.go +++ b/senders/discord/init.go @@ -46,7 +46,7 @@ func (sender *Sender) Init(senderSettings interface{}, logger moira.Logger, loca } sender.session, err = discordgo.New("Bot " + cfg.Token) if err != nil { - return fmt.Errorf("error creating discord session: %s", err) + return fmt.Errorf("error creating discord session: %w", err) } sender.logger = logger sender.frontURI = cfg.FrontURI diff --git a/senders/discord/response.go b/senders/discord/response.go index 41eac699d..e9ee82348 100644 --- a/senders/discord/response.go +++ b/senders/discord/response.go @@ -18,14 +18,14 @@ func (sender *Sender) getResponse(m *discordgo.MessageCreate, channel *discordgo case discordgo.ChannelTypeDM: err := sender.DataBase.SetUsernameID(messenger, "@"+m.Author.Username, channel.ID) if err != nil { - return "", fmt.Errorf("error while setting the channel ID for user: %s", err) + return "", fmt.Errorf("error while setting the channel ID for user: %w", err) } msg := fmt.Sprintf("Okay, %s, your id is %s", m.Author.Username, channel.ID) return msg, nil case discordgo.ChannelTypeGuildText: err := sender.DataBase.SetUsernameID(messenger, channel.Name, channel.ID) if err != nil { - return "", fmt.Errorf("error while setting the channel ID for text channel: %s", err) + return "", fmt.Errorf("error while setting the channel ID for text channel: %w", err) } msg := fmt.Sprintf("Hi, all!\nI will send alerts in this group (%s).", channel.Name) return msg, nil diff --git a/senders/discord/send.go b/senders/discord/send.go index e52f88937..a6dc4eb02 100644 --- a/senders/discord/send.go +++ b/senders/discord/send.go @@ -38,7 +38,7 @@ func (sender *Sender) SendEvents(events moira.NotificationEvents, contact moira. channelID, err := sender.getChannelID(contact.Value) if err != nil { - return fmt.Errorf("failed to get the channel ID: %s", err) + return fmt.Errorf("failed to get the channel ID: %w", err) } _, err = sender.session.ChannelMessageSendComplex(channelID, data) if err != nil { diff --git a/senders/mail/send.go b/senders/mail/send.go index dc65ab1a6..cd5d3f471 100644 --- a/senders/mail/send.go +++ b/senders/mail/send.go @@ -98,7 +98,7 @@ func (sender *Sender) makeMessage(events moira.NotificationEvents, contact moira func formatDescription(desc string) template.HTML { htmlDesc := blackfriday.Run([]byte(desc)) - htmlDescWithbr := strings.Replace(string(htmlDesc), "\n", "
", -1) + htmlDescWithbr := strings.ReplaceAll(string(htmlDesc), "\n", "
") return template.HTML(htmlDescWithbr) } diff --git a/senders/mail/send_test.go b/senders/mail/send_test.go index 99ab2ddfd..2c1a4895e 100644 --- a/senders/mail/send_test.go +++ b/senders/mail/send_test.go @@ -58,7 +58,6 @@ some other text _italics text_`, So(messageStr.String(), ShouldContainSubstring, "http://localhost/trigger/triggerID-0000000000001") So(messageStr.String(), ShouldContainSubstring, "italics text") So(messageStr.String(), ShouldContainSubstring, "bold text") - //fmt.Println(messageStr.String()) }) } diff --git a/senders/mattermost/sender.go b/senders/mattermost/sender.go index 0b514069f..9b87d8f97 100644 --- a/senders/mattermost/sender.go +++ b/senders/mattermost/sender.go @@ -47,7 +47,7 @@ func (sender *Sender) Init(senderSettings interface{}, logger moira.Logger, loca client := model.NewAPIv4Client(cfg.Url) if err != nil { - return fmt.Errorf("can not parse insecure_tls: %v", err) + return fmt.Errorf("can not parse insecure_tls: %w", err) } client.HTTPClient = &http.Client{ Transport: &http.Transport{ @@ -205,7 +205,7 @@ func (sender *Sender) sendMessage(ctx context.Context, message string, contact s sentPost, _, err := sender.client.CreatePost(ctx, &post) if err != nil { - return nil, fmt.Errorf("failed to send %s event message to Mattermost [%s]: %s", triggerID, contact, err) + return nil, fmt.Errorf("failed to send %s event message to Mattermost [%s]: %w", triggerID, contact, err) } return sentPost, nil diff --git a/senders/msteams/datatypes.go b/senders/msteams/datatypes.go index 90d7cb304..7c5ce43bd 100644 --- a/senders/msteams/datatypes.go +++ b/senders/msteams/datatypes.go @@ -74,7 +74,7 @@ type Action struct { MessageCard models an MSTeams compatible MessageCard { - "@context": "https://schema.org/extensions", + "@extensions": "https://schema.org/extensions", "@type": "MessageCard", "summary": "Moira Alert" "title" : "WARN Trigger Name [tag1]" @@ -106,7 +106,7 @@ MessageCard models an MSTeams compatible MessageCard } */ type MessageCard struct { - Context string `json:"@context"` + Context string `json:"@extensions"` MessageType string `json:"@type"` Summary string `json:"summary"` ThemeColor string `json:"themeColor"` diff --git a/senders/msteams/msteams.go b/senders/msteams/msteams.go index bf91c2f1b..dfe790df1 100644 --- a/senders/msteams/msteams.go +++ b/senders/msteams/msteams.go @@ -2,6 +2,7 @@ package msteams import ( "bytes" + "context" "encoding/json" "fmt" "io" @@ -15,7 +16,7 @@ import ( "github.com/russross/blackfriday/v2" ) -const context = "http://schema.org/extensions" +const extensions = "http://schema.org/extensions" const messageType = "MessageCard" const summary = "Moira Alert" const teamsBaseURL = "https://outlook.office.com/webhook/" @@ -94,7 +95,7 @@ func (sender *Sender) SendEvents(events moira.NotificationEvents, contact moira. return fmt.Errorf("failed to decode response: %w", err) } - //handle non 2xx responses + // handle non 2xx responses if response.StatusCode >= http.StatusBadRequest && response.StatusCode <= http.StatusNetworkAuthenticationRequired { return fmt.Errorf("server responded with a non 2xx code: %d", response.StatusCode) } @@ -131,7 +132,7 @@ func (sender *Sender) buildMessage(events moira.NotificationEvents, trigger moir state := events.GetCurrentState(throttled) return MessageCard{ - Context: context, + Context: extensions, MessageType: messageType, Summary: summary, ThemeColor: getColourForState(state), @@ -155,7 +156,7 @@ func (sender *Sender) buildRequest(events moira.NotificationEvents, contact moir return nil, err } - request, err := http.NewRequest(http.MethodPost, requestURL, bytes.NewBuffer(requestBody)) + request, err := http.NewRequestWithContext(context.Background(), http.MethodPost, requestURL, bytes.NewBuffer(requestBody)) if err != nil { return request, err } @@ -246,6 +247,6 @@ func getColourForState(state moira.State) string { case moira.StateNODATA: return Black default: - return White //unhandled state + return White // unhandled state } } diff --git a/senders/opsgenie/init.go b/senders/opsgenie/init.go index 5b627c6f1..03afa3709 100644 --- a/senders/opsgenie/init.go +++ b/senders/opsgenie/init.go @@ -51,7 +51,7 @@ func (sender *Sender) Init(senderSettings interface{}, logger moira.Logger, loca ApiKey: sender.apiKey, }) if err != nil { - return fmt.Errorf("error while creating opsgenie client: %s", err) + return fmt.Errorf("error while creating opsgenie client: %w", err) } sender.frontURI = cfg.FrontURI diff --git a/senders/opsgenie/send_test.go b/senders/opsgenie/send_test.go index 528a9c877..0cb378e8e 100644 --- a/senders/opsgenie/send_test.go +++ b/senders/opsgenie/send_test.go @@ -123,7 +123,7 @@ func TestBuildTitle(t *testing.T) { Convey("Build title that exceeds the title limit", t, func() { var reallyLongTag string for i := 0; i < 30; i++ { - reallyLongTag = reallyLongTag + "randomstring" + reallyLongTag += "randomstring" } Convey("without throttling", func() { diff --git a/senders/pagerduty/send.go b/senders/pagerduty/send.go index 315eb4664..8a37d101a 100644 --- a/senders/pagerduty/send.go +++ b/senders/pagerduty/send.go @@ -20,7 +20,7 @@ func (sender *Sender) SendEvents(events moira.NotificationEvents, contact moira. event := sender.buildEvent(events, contact, trigger, plots, throttled) _, err := pagerduty.ManageEventWithContext(context.Background(), event) if err != nil { - return fmt.Errorf("failed to post the event to the pagerduty contact %s : %s. ", contact.Value, err) + return fmt.Errorf("failed to post the event to the pagerduty contact %s : %w. ", contact.Value, err) } return nil } diff --git a/senders/pushover/pushover_test.go b/senders/pushover/pushover_test.go index 96ea0b894..1241edce6 100644 --- a/senders/pushover/pushover_test.go +++ b/senders/pushover/pushover_test.go @@ -149,7 +149,7 @@ func TestBuildTitle(t *testing.T) { Convey("Build title that exceeds the title limit", t, func() { var reallyLongTag string for i := 0; i < 30; i++ { - reallyLongTag = reallyLongTag + "randomstring" + reallyLongTag += "randomstring" } Convey("without throttling", func() { diff --git a/senders/script/script.go b/senders/script/script.go index 6d55e09ad..36c31d47c 100644 --- a/senders/script/script.go +++ b/senders/script/script.go @@ -125,7 +125,7 @@ func buildExecString(template string, trigger moira.TriggerData, contact moira.C moira.VariableTriggerName: trigger.Name, } for k, v := range templateVariables { - template = strings.Replace(template, k, v, -1) + template = strings.ReplaceAll(template, k, v) } return template } diff --git a/senders/slack/slack.go b/senders/slack/slack.go index bdb43f899..30ea83643 100644 --- a/senders/slack/slack.go +++ b/senders/slack/slack.go @@ -25,7 +25,7 @@ const ( messageMaxCharacters = 4000 - //see errors https://api.slack.com/methods/chat.postMessage + // see errors https://api.slack.com/methods/chat.postMessage ErrorTextChannelArchived = "is_archived" ErrorTextChannelNotFound = "channel_not_found" ErrorTextNotInChannel = "not_in_channel" diff --git a/senders/telegram/send.go b/senders/telegram/send.go index 9e557a58a..8d50759d7 100644 --- a/senders/telegram/send.go +++ b/senders/telegram/send.go @@ -2,6 +2,7 @@ package telegram import ( "bytes" + "errors" "fmt" "strings" @@ -146,7 +147,8 @@ func checkBrokenContactError(logger moira.Logger, err error) error { if err == nil { return nil } - if e, ok := err.(*telebot.APIError); ok { + var e *telebot.APIError + if ok := errors.Is(err, e); ok { logger.Debug(). Int("code", e.Code). String("msg", e.Message). diff --git a/senders/telegram/send_test.go b/senders/telegram/send_test.go index 3a77029ee..ef42ab37d 100644 --- a/senders/telegram/send_test.go +++ b/senders/telegram/send_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/pkg/errors" + logging "github.com/moira-alert/moira/logging/zerolog_adapter" "github.com/golang/mock/gomock" @@ -190,7 +192,9 @@ func TestCheckBrokenContactError(t *testing.T) { for _, brokenContactError := range brokenContactErrorsList { err := checkBrokenContactError(logger, brokenContactError) So(err, ShouldHaveSameTypeAs, moira.SenderBrokenContactError{}) - So(err.(moira.SenderBrokenContactError).SenderError, ShouldEqual, brokenContactError) + var convertedErr moira.SenderBrokenContactError + errors.As(err, &convertedErr) + So(convertedErr.SenderError, ShouldEqual, brokenContactError) } }) Convey("Other errors are returned as is", func() { @@ -211,7 +215,9 @@ func TestCheckBrokenContactError(t *testing.T) { userNotFoundError := fmt.Errorf("failed to get username uuid: nil returned") err := checkBrokenContactError(logger, userNotFoundError) So(err, ShouldHaveSameTypeAs, moira.SenderBrokenContactError{}) - So(err.(moira.SenderBrokenContactError).SenderError, ShouldEqual, userNotFoundError) + var convertedErr moira.SenderBrokenContactError + errors.As(err, &convertedErr) + So(convertedErr.SenderError, ShouldEqual, userNotFoundError) }) }) } diff --git a/senders/twilio/sms.go b/senders/twilio/sms.go index 8595041b3..a4e4d47d6 100644 --- a/senders/twilio/sms.go +++ b/senders/twilio/sms.go @@ -24,7 +24,7 @@ func (sender *twilioSenderSms) SendEvents(events moira.NotificationEvents, conta twilioMessage, err := twilio_client.NewMessage(sender.client, sender.APIFromPhone, contact.Value, twilio_client.Body(message)) if err != nil { - return fmt.Errorf("failed to send message to contact %s: %s", contact.Value, err) + return fmt.Errorf("failed to send message to contact %s: %w", contact.Value, err) } sender.logger.Debug(). diff --git a/senders/victorops/api/alert.go b/senders/victorops/api/alert.go index 78e3a4e40..b9d5a0f72 100644 --- a/senders/victorops/api/alert.go +++ b/senders/victorops/api/alert.go @@ -2,6 +2,7 @@ package api import ( "bytes" + "context" "encoding/json" "fmt" "io" @@ -42,9 +43,9 @@ func (client *Client) CreateAlert(routingKey string, alert CreateAlertRequest) e body, err := json.Marshal(alert) if err != nil { - return fmt.Errorf("error while encoding json: %s", err) + return fmt.Errorf("error while encoding json: %w", err) } - req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s", client.routingURL, routingKey), bytes.NewReader(body)) + req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, fmt.Sprintf("%s/%s", client.routingURL, routingKey), bytes.NewReader(body)) if err != nil { return err } @@ -54,7 +55,7 @@ func (client *Client) CreateAlert(routingKey string, alert CreateAlertRequest) e resp, err := client.httpClient.Do(req) if err != nil { - return fmt.Errorf("error while making the request to victorops: %s", err) + return fmt.Errorf("error while making the request to victorops: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { diff --git a/senders/victorops/send.go b/senders/victorops/send.go index 74af129c0..961c5bec8 100644 --- a/senders/victorops/send.go +++ b/senders/victorops/send.go @@ -16,7 +16,7 @@ func (sender *Sender) SendEvents(events moira.NotificationEvents, contact moira. createAlertRequest := sender.buildCreateAlertRequest(events, trigger, throttled, plots, time.Now().Unix()) err := sender.client.CreateAlert(contact.Value, createAlertRequest) if err != nil { - return fmt.Errorf("error while sending alert to victorops: %s", err) + return fmt.Errorf("error while sending alert to victorops: %w", err) } return nil } diff --git a/senders/webhook/request.go b/senders/webhook/request.go index a7f8d73ca..10e0f5ccc 100644 --- a/senders/webhook/request.go +++ b/senders/webhook/request.go @@ -2,6 +2,7 @@ package webhook import ( "bytes" + "context" "encoding/json" "net/http" "net/url" @@ -21,7 +22,7 @@ func (sender *Sender) buildRequest(events moira.NotificationEvents, contact moir if err != nil { return nil, err } - request, err := http.NewRequest("POST", requestURL, bytes.NewBuffer(requestBody)) + request, err := http.NewRequestWithContext(context.Background(), http.MethodPost, requestURL, bytes.NewBuffer(requestBody)) if err != nil { return request, err } @@ -80,7 +81,7 @@ func buildRequestURL(template string, trigger moira.TriggerData, contact moira.C (strings.HasPrefix(v, "http://") || strings.HasPrefix(v, "https://")) { value = v } - template = strings.Replace(template, k, value, -1) + template = strings.ReplaceAll(template, k, value) } return template } diff --git a/templating/templating.go b/templating/templating.go index 890540706..8b2101922 100644 --- a/templating/templating.go +++ b/templating/templating.go @@ -256,7 +256,7 @@ func Populate(name, description string, events []Event) (desc string, err error) defer func() { if errRecover := recover(); errRecover != nil { desc = description - err = fmt.Errorf("PANIC in populate: %v, Trigger name: %s, desc: %s, events:%#v", + err = fmt.Errorf("PANIC in populate: %w, Trigger name: %s, desc: %s, events:%#v", err, name, description, events) } }() diff --git a/worker/worker.go b/worker/worker.go index 811941749..fb1f43c94 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -39,7 +39,7 @@ func (worker *Worker) Run(stop <-chan struct{}) { Msg("Worker tries to acquire the lock...") lost, err := worker.lock.Acquire(stop) if err != nil { - switch err { + switch err { // nolint:errorlint case database.ErrLockAcquireInterrupted: return default: