From 91b094f4f443f6512ac773c73767c6196b7f82f4 Mon Sep 17 00:00:00 2001 From: Ludvig Lundgren Date: Fri, 20 May 2022 09:27:01 +0200 Subject: [PATCH] feat(confg): reload on save and refactor logging (#275) * feat(confg): reload on save * refactor(logging): rework --- cmd/autobrr/main.go | 72 ++++++------ cmd/autobrrctl/main.go | 4 +- go.mod | 8 +- go.sum | 6 +- internal/action/deluge.go | 69 ++++++----- internal/action/exec.go | 14 +-- internal/action/lidarr.go | 12 +- internal/action/qbittorrent.go | 50 ++++---- internal/action/radarr.go | 12 +- internal/action/run.go | 96 ++++++++------- internal/action/service.go | 11 +- internal/action/sonarr.go | 12 +- internal/action/whisparr.go | 12 +- internal/announce/announce.go | 42 +++---- internal/config/config.go | 90 +++++++++----- internal/database/action.go | 68 +++++------ internal/database/database.go | 14 ++- internal/database/download_client.go | 45 +++---- internal/database/feed.go | 44 +++---- internal/database/feed_cache.go | 25 ++-- internal/database/filter.go | 80 +++++++------ internal/database/indexer.go | 41 +++---- internal/database/irc.go | 92 ++++++++------- internal/database/notification.go | 41 ++++--- internal/database/postgres.go | 7 +- internal/database/release.go | 65 ++++++----- internal/database/sqlite.go | 5 +- internal/database/user.go | 29 ++--- internal/domain/config.go | 1 + internal/domain/indexer.go | 8 +- internal/domain/release.go | 22 ++-- internal/domain/release_test.go | 2 +- internal/download_client/connection.go | 40 +++---- internal/download_client/service.go | 16 ++- internal/events/subscribers.go | 18 +-- internal/feed/service.go | 51 ++++---- internal/feed/torznab.go | 4 +- internal/filter/service.go | 78 +++++++------ internal/http/auth.go | 4 +- internal/http/config.go | 14 +-- internal/http/server.go | 4 +- internal/indexer/api.go | 15 +-- internal/indexer/service.go | 44 +++---- internal/irc/handler.go | 85 +++++++------- internal/irc/service.go | 96 +++++++-------- internal/logger/logger.go | 155 ++++++++++++++++++------- internal/notification/discord.go | 12 +- internal/notification/service.go | 9 +- internal/release/service.go | 29 ++--- internal/scheduler/service.go | 15 ++- internal/server/server.go | 15 +-- internal/user/service.go | 1 + pkg/ggn/ggn.go | 7 +- pkg/lidarr/client.go | 26 ++--- pkg/lidarr/lidarr.go | 24 ++-- pkg/ptp/ptp.go | 7 +- 56 files changed, 995 insertions(+), 873 deletions(-) diff --git a/cmd/autobrr/main.go b/cmd/autobrr/main.go index fff3708..806a585 100644 --- a/cmd/autobrr/main.go +++ b/cmd/autobrr/main.go @@ -7,7 +7,6 @@ import ( "github.com/asaskevich/EventBus" "github.com/r3labs/sse/v2" - "github.com/rs/zerolog/log" "github.com/spf13/pflag" "github.com/autobrr/autobrr/internal/action" @@ -41,22 +40,27 @@ func main() { pflag.Parse() // read config - cfg := config.Read(configPath) + cfg := config.New(configPath, version) + + // init new logger + log := logger.New(cfg.Config) + + // init dynamic config + cfg.DynamicReload(log) // setup server-sent-events serverEvents := sse.New() serverEvents.AutoReplay = false - serverEvents.CreateStream("logs") + // register SSE hook on logger + log.RegisterSSEHook(serverEvents) + // setup internal eventbus bus := EventBus.New() - // setup logger - logger.Setup(cfg, serverEvents) - // open database connection - db, _ := database.NewDB(cfg) + db, _ := database.NewDB(cfg.Config, log) if err := db.Open(); err != nil { log.Fatal().Err(err).Msg("could not open db connection") } @@ -65,47 +69,47 @@ func main() { log.Info().Msgf("Version: %v", version) log.Info().Msgf("Commit: %v", commit) log.Info().Msgf("Build date: %v", date) - log.Info().Msgf("Log-level: %v", cfg.LogLevel) + log.Info().Msgf("Log-level: %v", cfg.Config.LogLevel) log.Info().Msgf("Using database: %v", db.Driver) // setup repos var ( - downloadClientRepo = database.NewDownloadClientRepo(db) - actionRepo = database.NewActionRepo(db, downloadClientRepo) - filterRepo = database.NewFilterRepo(db) - feedRepo = database.NewFeedRepo(db) - feedCacheRepo = database.NewFeedCacheRepo(db) - indexerRepo = database.NewIndexerRepo(db) - ircRepo = database.NewIrcRepo(db) - notificationRepo = database.NewNotificationRepo(db) - releaseRepo = database.NewReleaseRepo(db) - userRepo = database.NewUserRepo(db) + downloadClientRepo = database.NewDownloadClientRepo(log, db) + actionRepo = database.NewActionRepo(log, db, downloadClientRepo) + filterRepo = database.NewFilterRepo(log, db) + feedRepo = database.NewFeedRepo(log, db) + feedCacheRepo = database.NewFeedCacheRepo(log, db) + indexerRepo = database.NewIndexerRepo(log, db) + ircRepo = database.NewIrcRepo(log, db) + notificationRepo = database.NewNotificationRepo(log, db) + releaseRepo = database.NewReleaseRepo(log, db) + userRepo = database.NewUserRepo(log, db) ) // setup services var ( - schedulingService = scheduler.NewService() - apiService = indexer.NewAPIService() + schedulingService = scheduler.NewService(log) + apiService = indexer.NewAPIService(log) userService = user.NewService(userRepo) authService = auth.NewService(userService) - downloadClientService = download_client.NewService(downloadClientRepo) - actionService = action.NewService(actionRepo, downloadClientService, bus) - indexerService = indexer.NewService(cfg, indexerRepo, apiService, schedulingService) - filterService = filter.NewService(filterRepo, actionRepo, apiService, indexerService) - releaseService = release.NewService(releaseRepo, actionService, filterService) - ircService = irc.NewService(ircRepo, releaseService, indexerService) - notificationService = notification.NewService(notificationRepo) - feedService = feed.NewService(feedRepo, feedCacheRepo, releaseService, schedulingService) + downloadClientService = download_client.NewService(log, downloadClientRepo) + actionService = action.NewService(log, actionRepo, downloadClientService, bus) + indexerService = indexer.NewService(log, cfg.Config, indexerRepo, apiService, schedulingService) + filterService = filter.NewService(log, filterRepo, actionRepo, apiService, indexerService) + releaseService = release.NewService(log, releaseRepo, actionService, filterService) + ircService = irc.NewService(log, ircRepo, releaseService, indexerService) + notificationService = notification.NewService(log, notificationRepo) + feedService = feed.NewService(log, feedRepo, feedCacheRepo, releaseService, schedulingService) ) // register event subscribers - events.NewSubscribers(bus, notificationService, releaseService) + events.NewSubscribers(log, bus, notificationService, releaseService) errorChannel := make(chan error) go func() { httpServer := http.NewServer( - cfg, + cfg.Config, serverEvents, db, version, @@ -124,9 +128,9 @@ func main() { errorChannel <- httpServer.Open() }() - srv := server.NewServer(ircService, indexerService, feedService, schedulingService) - srv.Hostname = cfg.Host - srv.Port = cfg.Port + srv := server.NewServer(log, ircService, indexerService, feedService, schedulingService) + srv.Hostname = cfg.Config.Host + srv.Port = cfg.Config.Port sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM) @@ -139,7 +143,7 @@ func main() { for sig := range sigCh { switch sig { case syscall.SIGHUP: - log.Print("shutting down server sighup") + log.Log().Msg("shutting down server sighup") srv.Shutdown() db.Close() os.Exit(1) diff --git a/cmd/autobrrctl/main.go b/cmd/autobrrctl/main.go index 4dc9484..75caba2 100644 --- a/cmd/autobrrctl/main.go +++ b/cmd/autobrrctl/main.go @@ -39,12 +39,12 @@ func main() { } // open database connection - db, _ := database.NewDB(domain.Config{ConfigPath: configPath, DatabaseType: "sqlite"}) + db, _ := database.NewDB(&domain.Config{ConfigPath: configPath, DatabaseType: "sqlite"}, nil) if err := db.Open(); err != nil { log.Fatal("could not open db connection") } - userRepo := database.NewUserRepo(db) + userRepo := database.NewUserRepo(nil, db) switch cmd := flag.Arg(0); cmd { case "create-user": diff --git a/go.mod b/go.mod index 0f19ed6..f3164c0 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,16 @@ require ( github.com/dcarbone/zadapters/zstdlog v0.3.1 github.com/dustin/go-humanize v1.0.0 github.com/ergochat/irc-go v0.1.0 + github.com/fsnotify/fsnotify v1.5.1 github.com/gdm85/go-libdeluge v0.5.5 github.com/go-chi/chi v1.5.4 github.com/gorilla/sessions v1.2.1 + github.com/gosimple/slug v1.12.0 github.com/lib/pq v1.10.4 + github.com/moistari/rls v0.2.0 github.com/pkg/errors v0.9.1 github.com/r3labs/sse/v2 v2.7.2 + github.com/robfig/cron/v3 v3.0.1 github.com/rs/cors v1.8.0 github.com/rs/zerolog v1.26.1 github.com/spf13/pflag v1.0.5 @@ -36,11 +40,9 @@ require ( github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.10.0 // indirect - github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/gdm85/go-rencode v0.1.8 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/securecookie v1.1.1 // indirect - github.com/gosimple/slug v1.12.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.3.2 // indirect @@ -52,14 +54,12 @@ require ( github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mitchellh/mapstructure v1.4.2 // indirect - github.com/moistari/rls v0.2.0 // indirect github.com/nxadm/tail v1.4.6 // indirect github.com/onsi/ginkgo v1.14.2 // indirect github.com/onsi/gomega v1.10.1 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect - github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cast v1.4.1 // indirect diff --git a/go.sum b/go.sum index db57d0c..9483313 100644 --- a/go.sum +++ b/go.sum @@ -172,6 +172,8 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cytec/releaseparser v0.0.0-20200706155913-2341b265c370 h1:g9q5BGfDdhcXn4EmVZD8UydPXrvhSvgz3FRBn7zAJNs= +github.com/cytec/releaseparser v0.0.0-20200706155913-2341b265c370/go.mod h1:T6MvuEQy8BSy+4Aol7AjqObp2g3wTv2HjcFrGToHVVE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -297,9 +299,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -472,8 +474,6 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/moistari/rls v0.1.20 h1:RsLbJqzev3O/BnSuuiAkSL1VcsymHW1i1z6/rB4Lz6c= -github.com/moistari/rls v0.1.20/go.mod h1:2oVpWLhkuUzu2xqRINGnvvlcAGizZGMfMv8UYnntUCg= github.com/moistari/rls v0.2.0 h1:0+aJk8yNBKi/eAOhnQSz1pZoYcYYVnBUicl0WE75oAg= github.com/moistari/rls v0.2.0/go.mod h1:2oVpWLhkuUzu2xqRINGnvvlcAGizZGMfMv8UYnntUCg= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= diff --git a/internal/action/deluge.go b/internal/action/deluge.go index 41ee0f0..df02905 100644 --- a/internal/action/deluge.go +++ b/internal/action/deluge.go @@ -10,18 +10,17 @@ import ( "github.com/autobrr/autobrr/internal/domain" delugeClient "github.com/gdm85/go-libdeluge" - "github.com/rs/zerolog/log" ) func (s *service) deluge(action domain.Action, release domain.Release) error { - log.Debug().Msgf("action Deluge: %v", action.Name) + s.log.Debug().Msgf("action Deluge: %v", action.Name) var err error // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID) + s.log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID) return err } @@ -40,12 +39,12 @@ func (s *service) deluge(action domain.Action, release domain.Release) error { switch client.Type { case "DELUGE_V1": - if err = delugeV1(client, settings, action, release); err != nil { + if err = s.delugeV1(client, settings, action, release); err != nil { return err } case "DELUGE_V2": - if err = delugeV2(client, settings, action, release); err != nil { + if err = s.delugeV2(client, settings, action, release); err != nil { return err } } @@ -54,12 +53,12 @@ func (s *service) deluge(action domain.Action, release domain.Release) error { } func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error) { - log.Trace().Msgf("action Deluge: %v check rules", action.Name) + s.log.Trace().Msgf("action Deluge: %v check rules", action.Name) // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Stack().Err(err).Msgf("error finding client: %v ID %v", action.Name, action.ClientID) + s.log.Error().Stack().Err(err).Msgf("error finding client: %v ID %v", action.Name, action.ClientID) return false, err } @@ -88,7 +87,7 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error // perform connection to Deluge server err = deluge.Connect() if err != nil { - log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host) + s.log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host) return false, err } @@ -98,7 +97,7 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error if client.Settings.Rules.Enabled && !action.IgnoreRules { activeDownloads, err := deluge.TorrentsStatus(delugeClient.StateDownloading, nil) if err != nil { - log.Error().Stack().Err(err).Msg("Deluge - could not fetch downloading torrents") + s.log.Error().Stack().Err(err).Msg("Deluge - could not fetch downloading torrents") return false, err } @@ -107,7 +106,7 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error // if max active downloads reached, check speed and if lower than threshold add anyways if len(activeDownloads) >= client.Settings.Rules.MaxActiveDownloads { - log.Debug().Msg("max active downloads reached, skipping") + s.log.Debug().Msg("max active downloads reached, skipping") return false, nil // // TODO handle ignore slow torrents @@ -117,16 +116,16 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error // // gives type conversion errors // state, err := deluge.GetSessionStatus() // if err != nil { - // log.Error().Err(err).Msg("could not get session state") + // s.log.Error().Err(err).Msg("could not get session state") // return err // } // // if int64(state.DownloadRate)*1024 >= client.Settings.Rules.DownloadSpeedThreshold { - // log.Trace().Msg("max active downloads reached, skip adding") + // s.log.Trace().Msg("max active downloads reached, skip adding") // return nil // } // - // log.Trace().Msg("active downloads are slower than set limit, lets add it") + // s.log.Trace().Msg("active downloads are slower than set limit, lets add it") //} } } @@ -135,14 +134,14 @@ func (s *service) delugeCheckRulesCanDownload(action domain.Action) (bool, error return true, nil } -func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error { +func (s *service) delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error { deluge := delugeClient.NewV1(settings) // perform connection to Deluge server err := deluge.Connect() if err != nil { - log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host) + s.log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host) return err } @@ -150,14 +149,14 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act t, err := ioutil.ReadFile(release.TorrentTmpFile) if err != nil { - log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile) + s.log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile) return err } // encode file to base64 before sending to deluge encodedFile := base64.StdEncoding.EncodeToString(t) if encodedFile == "" { - log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile) + s.log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile) return err } @@ -174,7 +173,7 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act // parse and replace values in argument string before continuing savePathArgs, err := m.Parse(action.SavePath) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath) return err } @@ -189,25 +188,25 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act options.MaxUploadSpeed = &maxUL } - log.Trace().Msgf("action Deluge options: %+v", options) + s.log.Trace().Msgf("action Deluge options: %+v", options) torrentHash, err := deluge.AddTorrentFile(release.TorrentTmpFile, encodedFile, &options) if err != nil { - log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name) + s.log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name) return err } if action.Label != "" { p, err := deluge.LabelPlugin() if err != nil { - log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name) + s.log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name) return err } // parse and replace values in argument string before continuing labelArgs, err := m.Parse(action.Label) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label) return err } @@ -215,25 +214,25 @@ func delugeV1(client *domain.DownloadClient, settings delugeClient.Settings, act // TODO first check if label exists, if not, add it, otherwise set err = p.SetTorrentLabel(torrentHash, labelArgs) if err != nil { - log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name) + s.log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name) return err } } } - log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name) + s.log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name) return nil } -func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error { +func (s *service) delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, action domain.Action, release domain.Release) error { deluge := delugeClient.NewV2(settings) // perform connection to Deluge server err := deluge.Connect() if err != nil { - log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host) + s.log.Error().Stack().Err(err).Msgf("error logging into client: %v %v", client.Name, client.Host) return err } @@ -241,14 +240,14 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act t, err := ioutil.ReadFile(release.TorrentTmpFile) if err != nil { - log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile) + s.log.Error().Stack().Err(err).Msgf("could not read torrent file: %v", release.TorrentTmpFile) return err } // encode file to base64 before sending to deluge encodedFile := base64.StdEncoding.EncodeToString(t) if encodedFile == "" { - log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile) + s.log.Error().Stack().Err(err).Msgf("could not encode torrent file: %v", release.TorrentTmpFile) return err } @@ -265,7 +264,7 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act // parse and replace values in argument string before continuing savePathArgs, err := m.Parse(action.SavePath) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath) return err } @@ -280,25 +279,25 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act options.MaxUploadSpeed = &maxUL } - log.Trace().Msgf("action Deluge options: %+v", options) + s.log.Trace().Msgf("action Deluge options: %+v", options) torrentHash, err := deluge.AddTorrentFile(release.TorrentTmpFile, encodedFile, &options) if err != nil { - log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name) + s.log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, client.Name) return err } if action.Label != "" { p, err := deluge.LabelPlugin() if err != nil { - log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name) + s.log.Error().Stack().Err(err).Msgf("could not load label plugin: %v", client.Name) return err } // parse and replace values in argument string before continuing labelArgs, err := m.Parse(action.Label) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Label) return err } @@ -306,13 +305,13 @@ func delugeV2(client *domain.DownloadClient, settings delugeClient.Settings, act // TODO first check if label exists, if not, add it, otherwise set err = p.SetTorrentLabel(torrentHash, labelArgs) if err != nil { - log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name) + s.log.Error().Stack().Err(err).Msgf("could not set label: %v on client: %v", action.Label, client.Name) return err } } } - log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name) + s.log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", torrentHash, client.Name) return nil } diff --git a/internal/action/exec.go b/internal/action/exec.go index fd44e8e..d407833 100644 --- a/internal/action/exec.go +++ b/internal/action/exec.go @@ -6,17 +6,15 @@ import ( "time" "github.com/autobrr/autobrr/internal/domain" - - "github.com/rs/zerolog/log" ) func (s *service) execCmd(release domain.Release, action domain.Action) { - log.Debug().Msgf("action exec: %v release: %v", action.Name, release.TorrentName) + s.log.Debug().Msgf("action exec: %v release: %v", action.Name, release.TorrentName) // check if program exists cmd, err := exec.LookPath(action.ExecCmd) if err != nil { - log.Error().Stack().Err(err).Msgf("exec failed, could not find program: %v", action.ExecCmd) + s.log.Error().Stack().Err(err).Msgf("exec failed, could not find program: %v", action.ExecCmd) return } @@ -26,7 +24,7 @@ func (s *service) execCmd(release domain.Release, action domain.Action) { // parse and replace values in argument string before continuing parsedArgs, err := m.Parse(action.ExecArgs) if err != nil { - log.Error().Stack().Err(err).Msgf("exec failed, could not parse arguments: %v", action.ExecCmd) + s.log.Error().Stack().Err(err).Msgf("exec failed, could not parse arguments: %v", action.ExecCmd) return } @@ -42,12 +40,12 @@ func (s *service) execCmd(release domain.Release, action domain.Action) { output, err := command.CombinedOutput() if err != nil { // everything other than exit 0 is considered an error - log.Error().Stack().Err(err).Msgf("command: %v args: %v failed, torrent: %v", cmd, parsedArgs, release.TorrentTmpFile) + s.log.Error().Stack().Err(err).Msgf("command: %v args: %v failed, torrent: %v", cmd, parsedArgs, release.TorrentTmpFile) } - log.Trace().Msgf("executed command: '%v'", string(output)) + s.log.Trace().Msgf("executed command: '%v'", string(output)) duration := time.Since(start) - log.Info().Msgf("executed command: '%v', args: '%v' %v,%v, total time %v", cmd, parsedArgs, release.TorrentName, release.Indexer, duration) + s.log.Info().Msgf("executed command: '%v', args: '%v' %v,%v, total time %v", cmd, parsedArgs, release.TorrentName, release.Indexer, duration) } diff --git a/internal/action/lidarr.go b/internal/action/lidarr.go index 6723216..ba8125a 100644 --- a/internal/action/lidarr.go +++ b/internal/action/lidarr.go @@ -7,19 +7,17 @@ import ( "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/pkg/lidarr" - - "github.com/rs/zerolog/log" ) func (s *service) lidarr(release domain.Release, action domain.Action) ([]string, error) { - log.Trace().Msg("action LIDARR") + s.log.Trace().Msg("action LIDARR") // TODO validate data // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Err(err).Msgf("lidarr: error finding client: %v", action.ClientID) + s.log.Error().Err(err).Msgf("lidarr: error finding client: %v", action.ClientID) return nil, err } @@ -61,17 +59,17 @@ func (s *service) lidarr(release domain.Release, action domain.Action) ([]string rejections, err := arr.Push(r) if err != nil { - log.Error().Stack().Err(err).Msgf("lidarr: failed to push release: %v", r) + s.log.Error().Stack().Err(err).Msgf("lidarr: failed to push release: %v", r) return nil, err } if rejections != nil { - log.Debug().Msgf("lidarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) + s.log.Debug().Msgf("lidarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) return rejections, nil } - log.Debug().Msgf("lidarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) + s.log.Debug().Msgf("lidarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) return nil, nil } diff --git a/internal/action/qbittorrent.go b/internal/action/qbittorrent.go index 48ba8f6..8e3d3d5 100644 --- a/internal/action/qbittorrent.go +++ b/internal/action/qbittorrent.go @@ -5,8 +5,6 @@ import ( "strconv" "time" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/pkg/qbittorrent" ) @@ -15,7 +13,7 @@ const ReannounceMaxAttempts = 50 const ReannounceInterval = 7000 func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, release domain.Release) error { - log.Debug().Msgf("action qBittorrent: %v", action.Name) + s.log.Debug().Msgf("action qBittorrent: %v", action.Name) // macros handle args and replace vars m := NewMacro(release) @@ -29,7 +27,7 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel // parse and replace values in argument string before continuing actionArgs, err := m.Parse(action.SavePath) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.SavePath) return err } @@ -40,7 +38,7 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel // parse and replace values in argument string before continuing categoryArgs, err := m.Parse(action.Category) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Category) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Category) return err } @@ -50,7 +48,7 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel // parse and replace values in argument string before continuing tagsArgs, err := m.Parse(action.Tags) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Tags) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.Tags) return err } @@ -69,34 +67,34 @@ func (s *service) qbittorrent(qbt *qbittorrent.Client, action domain.Action, rel options["seedingTimeLimit"] = strconv.FormatInt(action.LimitSeedTime, 10) } - log.Trace().Msgf("action qBittorrent options: %+v", options) + s.log.Trace().Msgf("action qBittorrent options: %+v", options) err := qbt.AddTorrentFromFile(release.TorrentTmpFile, options) if err != nil { - log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, qbt.Name) + s.log.Error().Stack().Err(err).Msgf("could not add torrent %v to client: %v", release.TorrentTmpFile, qbt.Name) return err } if !action.Paused && !action.ReAnnounceSkip && release.TorrentHash != "" { err = s.checkTrackerStatus(qbt, action, release.TorrentHash) if err != nil { - log.Error().Stack().Err(err).Msgf("could not reannounce torrent: %v", release.TorrentHash) + s.log.Error().Stack().Err(err).Msgf("could not reannounce torrent: %v", release.TorrentHash) return err } } - log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", release.TorrentHash, qbt.Name) + s.log.Info().Msgf("torrent with hash %v successfully added to client: '%v'", release.TorrentHash, qbt.Name) return nil } func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, *qbittorrent.Client, error) { - log.Trace().Msgf("action qBittorrent: %v check rules", action.Name) + s.log.Trace().Msgf("action qBittorrent: %v check rules", action.Name) // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID) + s.log.Error().Stack().Err(err).Msgf("error finding client: %v", action.ClientID) return false, nil, err } @@ -118,7 +116,7 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, // save cookies? err = qbt.Login() if err != nil { - log.Error().Stack().Err(err).Msgf("error logging into client: %v", client.Host) + s.log.Error().Stack().Err(err).Msgf("error logging into client: %v", client.Host) return false, nil, err } @@ -126,7 +124,7 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, if client.Settings.Rules.Enabled && !action.IgnoreRules { activeDownloads, err := qbt.GetTorrentsActiveDownloads() if err != nil { - log.Error().Stack().Err(err).Msg("could not fetch downloading torrents") + s.log.Error().Stack().Err(err).Msg("could not fetch downloading torrents") return false, nil, err } @@ -139,20 +137,20 @@ func (s *service) qbittorrentCheckRulesCanDownload(action domain.Action) (bool, // check speeds of downloads info, err := qbt.GetTransferInfo() if err != nil { - log.Error().Err(err).Msg("could not get transfer info") + s.log.Error().Err(err).Msg("could not get transfer info") return false, nil, err } // if current transfer speed is more than threshold return out and skip // DlInfoSpeed is in bytes so lets convert to KB to match DownloadSpeedThreshold if info.DlInfoSpeed/1024 >= client.Settings.Rules.DownloadSpeedThreshold { - log.Debug().Msg("max active downloads reached, skipping") + s.log.Debug().Msg("max active downloads reached, skipping") return false, nil, nil } - log.Debug().Msg("active downloads are slower than set limit, lets add it") + s.log.Debug().Msg("active downloads are slower than set limit, lets add it") } else { - log.Debug().Msg("max active downloads reached, skipping") + s.log.Debug().Msg("max active downloads reached, skipping") return false, nil, nil } } @@ -181,20 +179,20 @@ func (s *service) checkTrackerStatus(qb *qbittorrent.Client, action domain.Actio } for attempts < maxAttempts { - log.Debug().Msgf("qBittorrent - run re-announce %v attempt: %v", hash, attempts) + s.log.Debug().Msgf("qBittorrent - run re-announce %v attempt: %v", hash, attempts) trackers, err := qb.GetTorrentTrackers(hash) if err != nil { - log.Error().Err(err).Msgf("qBittorrent - could not get trackers for torrent: %v", hash) + s.log.Error().Err(err).Msgf("qBittorrent - could not get trackers for torrent: %v", hash) return err } - log.Trace().Msgf("qBittorrent - run re-announce %v attempt: %v trackers (%+v)", hash, attempts, trackers) + s.log.Trace().Msgf("qBittorrent - run re-announce %v attempt: %v trackers (%+v)", hash, attempts, trackers) // check if status not working or something else working := findTrackerStatus(trackers) if working { - log.Debug().Msgf("qBittorrent - re-announce for %v OK", hash) + s.log.Debug().Msgf("qBittorrent - re-announce for %v OK", hash) announceOK = true @@ -202,10 +200,10 @@ func (s *service) checkTrackerStatus(qb *qbittorrent.Client, action domain.Actio return nil } - log.Trace().Msgf("qBittorrent - not working yet, lets re-announce %v attempt: %v", hash, attempts) + s.log.Trace().Msgf("qBittorrent - not working yet, lets re-announce %v attempt: %v", hash, attempts) err = qb.ReAnnounceTorrents([]string{hash}) if err != nil { - log.Error().Err(err).Msgf("qBittorrent - could not get re-announce torrent: %v", hash) + s.log.Error().Err(err).Msgf("qBittorrent - could not get re-announce torrent: %v", hash) return err } @@ -220,11 +218,11 @@ func (s *service) checkTrackerStatus(qb *qbittorrent.Client, action domain.Actio // delete on failure to reannounce if !announceOK && action.ReAnnounceDelete { - log.Debug().Msgf("qBittorrent - re-announce for %v took too long, deleting torrent", hash) + s.log.Debug().Msgf("qBittorrent - re-announce for %v took too long, deleting torrent", hash) err := qb.DeleteTorrents([]string{hash}, false) if err != nil { - log.Error().Stack().Err(err).Msgf("qBittorrent - could not delete torrent: %v", hash) + s.log.Error().Stack().Err(err).Msgf("qBittorrent - could not delete torrent: %v", hash) return err } } diff --git a/internal/action/radarr.go b/internal/action/radarr.go index 7f3340d..0515d24 100644 --- a/internal/action/radarr.go +++ b/internal/action/radarr.go @@ -6,19 +6,17 @@ import ( "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/pkg/radarr" - - "github.com/rs/zerolog/log" ) func (s *service) radarr(release domain.Release, action domain.Action) ([]string, error) { - log.Trace().Msg("action RADARR") + s.log.Trace().Msg("action RADARR") // TODO validate data // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Err(err).Msgf("radarr: error finding client: %v", action.ClientID) + s.log.Error().Err(err).Msgf("radarr: error finding client: %v", action.ClientID) return nil, err } @@ -54,17 +52,17 @@ func (s *service) radarr(release domain.Release, action domain.Action) ([]string rejections, err := arr.Push(r) if err != nil { - log.Error().Stack().Err(err).Msgf("radarr: failed to push release: %v", r) + s.log.Error().Stack().Err(err).Msgf("radarr: failed to push release: %v", r) return nil, err } if rejections != nil { - log.Debug().Msgf("radarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) + s.log.Debug().Msgf("radarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) return rejections, nil } - log.Debug().Msgf("radarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) + s.log.Debug().Msgf("radarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) return nil, nil } diff --git a/internal/action/run.go b/internal/action/run.go index 21cfd30..8f9e929 100644 --- a/internal/action/run.go +++ b/internal/action/run.go @@ -9,8 +9,6 @@ import ( "path" "time" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" ) @@ -22,11 +20,11 @@ func (s *service) RunActions(actions []domain.Action, release domain.Release) er continue } - log.Debug().Msgf("process action: %v for '%v'", action.Name, release.TorrentName) + s.log.Debug().Msgf("process action: %v for '%v'", action.Name, release.TorrentName) err := s.runAction(action, release) if err != nil { - log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName) + s.log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName) s.bus.Publish("release:store-action-status", &domain.ReleaseActionStatus{ ReleaseID: release.ID, @@ -71,7 +69,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st case domain.ActionTypeExec: if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) break } } @@ -81,7 +79,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st case domain.ActionTypeWatchFolder: if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) break } } @@ -91,7 +89,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st case domain.ActionTypeWebhook: if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) break } } @@ -101,7 +99,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2: canDownload, err := s.delugeCheckRulesCanDownload(*action) if err != nil { - log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) + s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) break } if !canDownload { @@ -111,21 +109,21 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) break } } err = s.deluge(*action, release) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to Deluge") + s.log.Error().Stack().Err(err).Msg("error sending torrent to Deluge") break } case domain.ActionTypeQbittorrent: canDownload, client, err := s.qbittorrentCheckRulesCanDownload(*action) if err != nil { - log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) + s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) break } if !canDownload { @@ -135,47 +133,47 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) break } } err = s.qbittorrent(client, *action, release) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent") + s.log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent") break } case domain.ActionTypeRadarr: rejections, err = s.radarr(release, *action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to radarr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to radarr") break } case domain.ActionTypeSonarr: rejections, err = s.sonarr(release, *action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to sonarr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to sonarr") break } case domain.ActionTypeLidarr: rejections, err = s.lidarr(release, *action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to lidarr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to lidarr") break } case domain.ActionTypeWhisparr: rejections, err = s.whisparr(release, *action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to whisparr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to whisparr") break } default: - log.Warn().Msgf("unsupported action type: %v", action.Type) + s.log.Warn().Msgf("unsupported action type: %v", action.Type) return rejections, err } @@ -205,7 +203,7 @@ func (s *service) RunAction(action *domain.Action, release domain.Release) ([]st } if err != nil { - log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName) + s.log.Err(err).Stack().Msgf("process action failed: %v for '%v'", action.Name, release.TorrentName) rlsActionStatus.Status = domain.ReleasePushStatusErr rlsActionStatus.Rejections = []string{err.Error()} @@ -243,7 +241,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error case domain.ActionTypeExec: if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) return err } } @@ -253,7 +251,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error case domain.ActionTypeWatchFolder: if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) return err } } @@ -263,7 +261,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error case domain.ActionTypeWebhook: if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) return err } } @@ -273,7 +271,7 @@ func (s *service) runAction(action domain.Action, release domain.Release) error case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2: canDownload, err := s.delugeCheckRulesCanDownload(action) if err != nil { - log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) + s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) return err } if !canDownload { @@ -283,21 +281,21 @@ func (s *service) runAction(action domain.Action, release domain.Release) error if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) return err } } err = s.deluge(action, release) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to Deluge") + s.log.Error().Stack().Err(err).Msg("error sending torrent to Deluge") return err } case domain.ActionTypeQbittorrent: canDownload, client, err := s.qbittorrentCheckRulesCanDownload(action) if err != nil { - log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) + s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) return err } if !canDownload { @@ -307,47 +305,47 @@ func (s *service) runAction(action domain.Action, release domain.Release) error if release.TorrentTmpFile == "" { if err := release.DownloadTorrentFile(); err != nil { - log.Error().Stack().Err(err) + s.log.Error().Stack().Err(err) return err } } err = s.qbittorrent(client, action, release) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent") + s.log.Error().Stack().Err(err).Msg("error sending torrent to qBittorrent") return err } case domain.ActionTypeRadarr: rejections, err = s.radarr(release, action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to radarr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to radarr") return err } case domain.ActionTypeSonarr: rejections, err = s.sonarr(release, action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to sonarr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to sonarr") return err } case domain.ActionTypeLidarr: rejections, err = s.lidarr(release, action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to lidarr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to lidarr") return err } case domain.ActionTypeWhisparr: rejections, err = s.whisparr(release, action) if err != nil { - log.Error().Stack().Err(err).Msg("error sending torrent to whisparr") + s.log.Error().Stack().Err(err).Msg("error sending torrent to whisparr") return err } default: - log.Warn().Msgf("unsupported action: %v type: %v", action.Name, action.Type) + s.log.Warn().Msgf("unsupported action: %v type: %v", action.Name, action.Type) return nil } @@ -399,13 +397,13 @@ func (s *service) CheckCanDownload(actions []domain.Action) bool { continue } - log.Debug().Msgf("action-service: check can download action: %v", action.Name) + s.log.Debug().Msgf("action-service: check can download action: %v", action.Name) switch action.Type { case domain.ActionTypeDelugeV1, domain.ActionTypeDelugeV2: canDownload, err := s.delugeCheckRulesCanDownload(action) if err != nil { - log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) + s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) continue } if !canDownload { @@ -417,7 +415,7 @@ func (s *service) CheckCanDownload(actions []domain.Action) bool { case domain.ActionTypeQbittorrent: canDownload, _, err := s.qbittorrentCheckRulesCanDownload(action) if err != nil { - log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) + s.log.Error().Stack().Err(err).Msgf("error checking client rules: %v", action.Name) continue } if !canDownload { @@ -432,7 +430,7 @@ func (s *service) CheckCanDownload(actions []domain.Action) bool { } func (s *service) test(name string) { - log.Info().Msgf("action TEST: %v", name) + s.log.Info().Msgf("action TEST: %v", name) } func (s *service) watchFolder(action domain.Action, release domain.Release) { @@ -441,15 +439,15 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) { // parse and replace values in argument string before continuing watchFolderArgs, err := m.Parse(action.WatchFolder) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WatchFolder) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WatchFolder) } - log.Trace().Msgf("action WATCH_FOLDER: %v file: %v", watchFolderArgs, release.TorrentTmpFile) + s.log.Trace().Msgf("action WATCH_FOLDER: %v file: %v", watchFolderArgs, release.TorrentTmpFile) // Open original file original, err := os.Open(release.TorrentTmpFile) if err != nil { - log.Error().Stack().Err(err).Msgf("could not open temp file '%v'", release.TorrentTmpFile) + s.log.Error().Stack().Err(err).Msgf("could not open temp file '%v'", release.TorrentTmpFile) return } defer original.Close() @@ -460,7 +458,7 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) { // Create new file newFile, err := os.Create(fullFileName) if err != nil { - log.Error().Stack().Err(err).Msgf("could not create new temp file '%v'", fullFileName) + s.log.Error().Stack().Err(err).Msgf("could not create new temp file '%v'", fullFileName) return } defer newFile.Close() @@ -468,11 +466,11 @@ func (s *service) watchFolder(action domain.Action, release domain.Release) { // Copy file _, err = io.Copy(newFile, original) if err != nil { - log.Error().Stack().Err(err).Msgf("could not copy file %v to watch folder", fullFileName) + s.log.Error().Stack().Err(err).Msgf("could not copy file %v to watch folder", fullFileName) return } - log.Info().Msgf("saved file to watch folder: %v", fullFileName) + s.log.Info().Msgf("saved file to watch folder: %v", fullFileName) } func (s *service) webhook(action domain.Action, release domain.Release) { @@ -481,12 +479,12 @@ func (s *service) webhook(action domain.Action, release domain.Release) { // parse and replace values in argument string before continuing dataArgs, err := m.Parse(action.WebhookData) if err != nil { - log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WebhookData) + s.log.Error().Stack().Err(err).Msgf("could not parse macro: %v", action.WebhookData) return } - log.Trace().Msgf("action WEBHOOK: '%v' file: %v", action.Name, release.TorrentName) - log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData) + s.log.Trace().Msgf("action WEBHOOK: '%v' file: %v", action.Name, release.TorrentName) + s.log.Trace().Msgf("webhook action '%v' - host: %v data: %v", action.Name, action.WebhookHost, action.WebhookData) t := &http.Transport{ TLSClientConfig: &tls.Config{ @@ -498,7 +496,7 @@ func (s *service) webhook(action domain.Action, release domain.Release) { req, err := http.NewRequest(http.MethodPost, action.WebhookHost, bytes.NewBufferString(dataArgs)) if err != nil { - log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost) + s.log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost) return } @@ -507,13 +505,13 @@ func (s *service) webhook(action domain.Action, release domain.Release) { res, err := client.Do(req) if err != nil { - log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost) + s.log.Error().Err(err).Msgf("webhook client request error: %v", action.WebhookHost) return } defer res.Body.Close() - log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, dataArgs) + s.log.Info().Msgf("successfully ran webhook action: '%v' to: %v payload: %v", action.Name, action.WebhookHost, dataArgs) return } diff --git a/internal/action/service.go b/internal/action/service.go index deb3dee..9822187 100644 --- a/internal/action/service.go +++ b/internal/action/service.go @@ -7,6 +7,7 @@ import ( "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/internal/download_client" + "github.com/autobrr/autobrr/internal/logger" ) type Service interface { @@ -22,13 +23,19 @@ type Service interface { } type service struct { + log logger.Logger repo domain.ActionRepo clientSvc download_client.Service bus EventBus.Bus } -func NewService(repo domain.ActionRepo, clientSvc download_client.Service, bus EventBus.Bus) Service { - return &service{repo: repo, clientSvc: clientSvc, bus: bus} +func NewService(log logger.Logger, repo domain.ActionRepo, clientSvc download_client.Service, bus EventBus.Bus) Service { + return &service{ + log: log, + repo: repo, + clientSvc: clientSvc, + bus: bus, + } } func (s *service) Store(ctx context.Context, action domain.Action) (*domain.Action, error) { diff --git a/internal/action/sonarr.go b/internal/action/sonarr.go index bcd4566..3979613 100644 --- a/internal/action/sonarr.go +++ b/internal/action/sonarr.go @@ -6,19 +6,17 @@ import ( "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/pkg/sonarr" - - "github.com/rs/zerolog/log" ) func (s *service) sonarr(release domain.Release, action domain.Action) ([]string, error) { - log.Trace().Msg("action SONARR") + s.log.Trace().Msg("action SONARR") // TODO validate data // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Err(err).Msgf("sonarr: error finding client: %v", action.ClientID) + s.log.Error().Err(err).Msgf("sonarr: error finding client: %v", action.ClientID) return nil, err } @@ -54,17 +52,17 @@ func (s *service) sonarr(release domain.Release, action domain.Action) ([]string rejections, err := arr.Push(r) if err != nil { - log.Error().Stack().Err(err).Msgf("sonarr: failed to push release: %v", r) + s.log.Error().Stack().Err(err).Msgf("sonarr: failed to push release: %v", r) return nil, err } if rejections != nil { - log.Debug().Msgf("sonarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) + s.log.Debug().Msgf("sonarr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) return rejections, nil } - log.Debug().Msgf("sonarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) + s.log.Debug().Msgf("sonarr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) return nil, nil } diff --git a/internal/action/whisparr.go b/internal/action/whisparr.go index 22451e3..0438db5 100644 --- a/internal/action/whisparr.go +++ b/internal/action/whisparr.go @@ -6,19 +6,17 @@ import ( "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/pkg/whisparr" - - "github.com/rs/zerolog/log" ) func (s *service) whisparr(release domain.Release, action domain.Action) ([]string, error) { - log.Trace().Msg("action WHISPARR") + s.log.Trace().Msg("action WHISPARR") // TODO validate data // get client for action client, err := s.clientSvc.FindByID(context.TODO(), action.ClientID) if err != nil { - log.Error().Err(err).Msgf("whisparr: error finding client: %v", action.ClientID) + s.log.Error().Err(err).Msgf("whisparr: error finding client: %v", action.ClientID) return nil, err } @@ -54,17 +52,17 @@ func (s *service) whisparr(release domain.Release, action domain.Action) ([]stri rejections, err := arr.Push(r) if err != nil { - log.Error().Stack().Err(err).Msgf("whisparr: failed to push release: %v", r) + s.log.Error().Stack().Err(err).Msgf("whisparr: failed to push release: %v", r) return nil, err } if rejections != nil { - log.Debug().Msgf("whisparr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) + s.log.Debug().Msgf("whisparr: release push rejected: %v, indexer %v to %v reasons: '%v'", r.Title, r.Indexer, client.Host, rejections) return rejections, nil } - log.Debug().Msgf("whisparr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) + s.log.Debug().Msgf("whisparr: successfully pushed release: %v, indexer %v to %v", r.Title, r.Indexer, client.Host) return nil, nil } diff --git a/internal/announce/announce.go b/internal/announce/announce.go index daa0b14..12f508c 100644 --- a/internal/announce/announce.go +++ b/internal/announce/announce.go @@ -9,10 +9,10 @@ import ( "strings" "text/template" + "github.com/rs/zerolog" + "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/internal/release" - - "github.com/rs/zerolog/log" ) type Processor interface { @@ -20,6 +20,7 @@ type Processor interface { } type announceProcessor struct { + log zerolog.Logger indexer *domain.IndexerDefinition releaseSvc release.Service @@ -27,8 +28,9 @@ type announceProcessor struct { queues map[string]chan string } -func NewAnnounceProcessor(releaseSvc release.Service, indexer *domain.IndexerDefinition) Processor { +func NewAnnounceProcessor(log zerolog.Logger, releaseSvc release.Service, indexer *domain.IndexerDefinition) Processor { ap := &announceProcessor{ + log: log, releaseSvc: releaseSvc, indexer: indexer, } @@ -46,7 +48,7 @@ func (a *announceProcessor) setupQueues() { channel = strings.ToLower(channel) queues[channel] = make(chan string, 128) - log.Trace().Msgf("announce: setup queue: %v", channel) + a.log.Trace().Msgf("announce: setup queue: %v", channel) } a.queues = queues @@ -55,9 +57,9 @@ func (a *announceProcessor) setupQueues() { func (a *announceProcessor) setupQueueConsumers() { for queueName, queue := range a.queues { go func(name string, q chan string) { - log.Trace().Msgf("announce: setup queue consumer: %v", name) + a.log.Trace().Msgf("announce: setup queue consumer: %v", name) a.processQueue(q) - log.Trace().Msgf("announce: queue consumer stopped: %v", name) + a.log.Trace().Msgf("announce: queue consumer stopped: %v", name) }(queueName, queue) } } @@ -71,43 +73,43 @@ func (a *announceProcessor) processQueue(queue chan string) { for _, pattern := range a.indexer.Parse.Lines { line, err := a.getNextLine(queue) if err != nil { - log.Error().Stack().Err(err).Msg("could not get line from queue") + a.log.Error().Stack().Err(err).Msg("could not get line from queue") return } - log.Trace().Msgf("announce: process line: %v", line) + a.log.Trace().Msgf("announce: process line: %v", line) // check should ignore match, err := a.parseExtract(pattern.Pattern, pattern.Vars, tmpVars, line) if err != nil { - log.Debug().Msgf("error parsing extract: %v", line) + a.log.Debug().Msgf("error parsing extract: %v", line) parseFailed = true break } if !match { - log.Debug().Msgf("line not matching expected regex pattern: %v", line) + a.log.Debug().Msgf("line not matching expected regex pattern: %v", line) parseFailed = true break } } if parseFailed { - log.Trace().Msg("announce: parse failed") + a.log.Trace().Msg("announce: parse failed") continue } rls, err := domain.NewRelease(a.indexer.Identifier) if err != nil { - log.Error().Err(err).Msg("could not create new release") + a.log.Error().Err(err).Msg("could not create new release") continue } // on lines matched err = a.onLinesMatched(a.indexer, tmpVars, rls) if err != nil { - log.Debug().Msgf("error match line: %v", "") + a.log.Debug().Msgf("error match line: %v", "") continue } @@ -135,7 +137,7 @@ func (a *announceProcessor) AddLineToQueue(channel string, line string) error { } queue <- line - log.Trace().Msgf("announce: queued line: %v", line) + a.log.Trace().Msgf("announce: queued line: %v", line) return nil } @@ -144,7 +146,7 @@ func (a *announceProcessor) parseExtract(pattern string, vars []string, tmpVars rxp, err := regExMatch(pattern, line) if err != nil { - log.Debug().Msgf("did not match expected line: %v", line) + a.log.Debug().Msgf("did not match expected line: %v", line) } if rxp == nil { @@ -171,21 +173,21 @@ func (a *announceProcessor) onLinesMatched(def *domain.IndexerDefinition, vars m err = rls.MapVars(def, vars) if err != nil { - log.Error().Stack().Err(err).Msg("announce: could not map vars for release") + a.log.Error().Stack().Err(err).Msg("announce: could not map vars for release") return err } // parse fields err = rls.ParseString(rls.TorrentName) if err != nil { - log.Error().Stack().Err(err).Msg("announce: could not parse release") + a.log.Error().Stack().Err(err).Msg("announce: could not parse release") return err } // parse torrentUrl err = def.Parse.ParseTorrentUrl(vars, def.SettingsMap, rls) if err != nil { - log.Error().Stack().Err(err).Msg("announce: could not parse torrent url") + a.log.Error().Stack().Err(err).Msg("announce: could not parse torrent url") return err } @@ -221,14 +223,14 @@ func (a *announceProcessor) processTorrentUrl(match string, vars map[string]stri // setup text template to inject variables into tmpl, err := template.New("torrenturl").Parse(match) if err != nil { - log.Error().Err(err).Msg("could not create torrent url template") + a.log.Error().Err(err).Msg("could not create torrent url template") return "", err } var b bytes.Buffer err = tmpl.Execute(&b, &tmpVars) if err != nil { - log.Error().Err(err).Msg("could not write torrent url template output") + a.log.Error().Err(err).Msg("could not write torrent url template output") return "", err } diff --git a/internal/config/config.go b/internal/config/config.go index 0bf5254..bc3328b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,32 +6,15 @@ import ( "os" "path" "path/filepath" + "sync" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" + "github.com/fsnotify/fsnotify" "github.com/spf13/viper" ) -var Config domain.Config - -func Defaults() domain.Config { - return domain.Config{ - Host: "localhost", - Port: 7474, - LogLevel: "TRACE", - LogPath: "", - BaseURL: "/", - SessionSecret: "secret-session-key", - CustomDefinitions: "", - DatabaseType: "sqlite", - PostgresHost: "", - PostgresPort: 0, - PostgresDatabase: "", - PostgresUser: "", - PostgresPass: "", - } -} - func writeConfig(configPath string, configFile string) error { path := filepath.Join(configPath, configFile) @@ -108,9 +91,45 @@ sessionSecret = "secret-session-key"`) return nil } -func Read(configPath string) domain.Config { - config := Defaults() +type Config interface { + DynamicReload(log logger.Logger) +} +type AppConfig struct { + Config *domain.Config + m sync.Mutex +} + +func New(configPath string, version string) *AppConfig { + c := &AppConfig{} + c.defaults() + c.Config.Version = version + + c.load(configPath) + + return c +} + +func (c *AppConfig) defaults() { + c.Config = &domain.Config{ + Version: "dev", + Host: "localhost", + Port: 7474, + LogLevel: "TRACE", + LogPath: "", + BaseURL: "/", + SessionSecret: "secret-session-key", + CustomDefinitions: "", + DatabaseType: "sqlite", + PostgresHost: "", + PostgresPort: 0, + PostgresDatabase: "", + PostgresUser: "", + PostgresPass: "", + } +} + +func (c *AppConfig) load(configPath string) { // or use viper.SetDefault(val, def) //viper.SetDefault("host", config.Host) //viper.SetDefault("port", config.Port) @@ -133,7 +152,6 @@ func Read(configPath string) domain.Config { } viper.SetConfigFile(path.Join(configPath, "config.toml")) - config.ConfigPath = configPath } else { viper.SetConfigName("config") @@ -148,11 +166,27 @@ func Read(configPath string) domain.Config { log.Printf("config read error: %q", err) } - if err := viper.Unmarshal(&config); err != nil { + if err := viper.Unmarshal(&c.Config); err != nil { log.Fatalf("Could not unmarshal config file: %v", viper.ConfigFileUsed()) } - - Config = config - - return config +} + +func (c *AppConfig) DynamicReload(log logger.Logger) { + viper.OnConfigChange(func(e fsnotify.Event) { + c.m.Lock() + + logLevel := viper.GetString("logLevel") + c.Config.LogLevel = logLevel + log.SetLogLevel(c.Config.LogLevel) + + logPath := viper.GetString("logPath") + c.Config.LogPath = logPath + + log.Debug().Msg("config file reloaded!") + + c.m.Unlock() + }) + viper.WatchConfig() + + return } diff --git a/internal/database/action.go b/internal/database/action.go index 3e5ecd6..72fab31 100644 --- a/internal/database/action.go +++ b/internal/database/action.go @@ -6,18 +6,20 @@ import ( "encoding/json" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" sq "github.com/Masterminds/squirrel" - "github.com/rs/zerolog/log" ) type ActionRepo struct { + log logger.Logger db *DB clientRepo domain.DownloadClientRepo } -func NewActionRepo(db *DB, clientRepo domain.DownloadClientRepo) domain.ActionRepo { +func NewActionRepo(log logger.Logger, db *DB, clientRepo domain.DownloadClientRepo) domain.ActionRepo { return &ActionRepo{ + log: log, db: db, clientRepo: clientRepo, } @@ -85,13 +87,13 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) ( query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.findByFilterID: error building query") + r.log.Error().Stack().Err(err).Msg("action.findByFilterID: error building query") return nil, err } rows, err := tx.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("action.findByFilterID: query error") + r.log.Error().Stack().Err(err).Msg("action.findByFilterID: query error") return nil, err } @@ -110,7 +112,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) ( var paused, ignoreRules sql.NullBool if err := rows.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &clientID); err != nil { - log.Error().Stack().Err(err).Msg("action.findByFilterID: error scanning row") + r.log.Error().Stack().Err(err).Msg("action.findByFilterID: error scanning row") return nil, err } @@ -139,7 +141,7 @@ func (r *ActionRepo) findByFilterID(ctx context.Context, tx *Tx, filterID int) ( actions = append(actions, &a) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("action.findByFilterID: row error") + r.log.Error().Stack().Err(err).Msg("action.findByFilterID: row error") return nil, err } @@ -166,13 +168,13 @@ func (r *ActionRepo) attachDownloadClient(ctx context.Context, tx *Tx, clientID query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error building query") + r.log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error building query") return nil, err } row := tx.QueryRowContext(ctx, query, args...) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error query row") + r.log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error query row") return nil, err } @@ -180,13 +182,13 @@ func (r *ActionRepo) attachDownloadClient(ctx context.Context, tx *Tx, clientID var settingsJsonStr string if err := row.Scan(&client.ID, &client.Name, &client.Type, &client.Enabled, &client.Host, &client.Port, &client.TLS, &client.TLSSkipVerify, &client.Username, &client.Password, &settingsJsonStr); err != nil { - log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error scanning row") + r.log.Error().Stack().Err(err).Msg("action.attachDownloadClient: error scanning row") return nil, err } if settingsJsonStr != "" { if err := json.Unmarshal([]byte(settingsJsonStr), &client.Settings); err != nil { - log.Error().Stack().Err(err).Msgf("action.attachDownloadClient: could not marshal download client settings %v", settingsJsonStr) + r.log.Error().Stack().Err(err).Msgf("action.attachDownloadClient: could not marshal download client settings %v", settingsJsonStr) return nil, err } } @@ -228,13 +230,13 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.list: error building query") + r.log.Error().Stack().Err(err).Msg("action.list: error building query") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("action.list: error executing query") + r.log.Error().Stack().Err(err).Msg("action.list: error executing query") return nil, err } @@ -251,7 +253,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) { var paused, ignoreRules sql.NullBool if err := rows.Scan(&a.ID, &a.Name, &a.Type, &a.Enabled, &execCmd, &execArgs, &watchFolder, &category, &tags, &label, &savePath, &paused, &ignoreRules, &limitDl, &limitUl, &limitRatio, &limitSeedTime, &a.ReAnnounceSkip, &a.ReAnnounceDelete, &a.ReAnnounceInterval, &a.ReAnnounceMaxAttempts, &webhookHost, &webhookType, &webhookMethod, &webhookData, &clientID); err != nil { - log.Error().Stack().Err(err).Msg("action.list: error scanning row") + r.log.Error().Stack().Err(err).Msg("action.list: error scanning row") return nil, err } @@ -277,7 +279,7 @@ func (r *ActionRepo) List(ctx context.Context) ([]domain.Action, error) { actions = append(actions, a) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("action.list: row error") + r.log.Error().Stack().Err(err).Msg("action.list: row error") return nil, err } @@ -291,17 +293,17 @@ func (r *ActionRepo) Delete(actionID int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.delete: error building query") + r.log.Error().Stack().Err(err).Msg("action.delete: error building query") return err } _, err = r.db.handler.Exec(query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("action.delete: error executing query") + r.log.Error().Stack().Err(err).Msg("action.delete: error executing query") return err } - log.Debug().Msgf("action.delete: %v", actionID) + r.log.Debug().Msgf("action.delete: %v", actionID) return nil } @@ -313,17 +315,17 @@ func (r *ActionRepo) DeleteByFilterID(ctx context.Context, filterID int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error building query") + r.log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error executing query") + r.log.Error().Stack().Err(err).Msg("action.deleteByFilterID: error executing query") return err } - log.Debug().Msgf("action.deleteByFilterID: %v", filterID) + r.log.Debug().Msgf("action.deleteByFilterID: %v", filterID) return nil } @@ -413,11 +415,11 @@ func (r *ActionRepo) Store(ctx context.Context, action domain.Action) (*domain.A err := queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("action.store: error executing query") + r.log.Error().Stack().Err(err).Msg("action.store: error executing query") return nil, err } - log.Debug().Msgf("action.store: added new %v", retID) + r.log.Debug().Msgf("action.store: added new %v", retID) action.ID = int(retID) return &action, nil @@ -478,17 +480,17 @@ func (r *ActionRepo) Update(ctx context.Context, action domain.Action) (*domain. query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.update: error building query") + r.log.Error().Stack().Err(err).Msg("action.update: error building query") return nil, err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("action.update: error executing query") + r.log.Error().Stack().Err(err).Msg("action.update: error executing query") return nil, err } - log.Debug().Msgf("action.update: %v", action.ID) + r.log.Debug().Msgf("action.update: %v", action.ID) return &action, nil } @@ -507,12 +509,12 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A deleteQuery, deleteArgs, err := deleteQueryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error building query") + r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error building query") return nil, err } _, err = tx.ExecContext(ctx, deleteQuery, deleteArgs...) if err != nil { - log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query") + r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query") return nil, err } @@ -600,18 +602,18 @@ func (r *ActionRepo) StoreFilterActions(ctx context.Context, actions []*domain.A err = queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query") + r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error executing query") return nil, err } action.ID = retID - log.Debug().Msgf("action.StoreFilterActions: store '%v' type: '%v' on filter: %v", action.Name, action.Type, filterID) + r.log.Debug().Msgf("action.StoreFilterActions: store '%v' type: '%v' on filter: %v", action.Name, action.Type, filterID) } err = tx.Commit() if err != nil { - log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error updating actions") + r.log.Error().Stack().Err(err).Msg("action.StoreFilterActions: error updating actions") return nil, err } @@ -629,17 +631,17 @@ func (r *ActionRepo) ToggleEnabled(actionID int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.toggleEnabled: error building query") + r.log.Error().Stack().Err(err).Msg("action.toggleEnabled: error building query") return err } _, err = r.db.handler.Exec(query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("action.toggleEnabled: error executing query") + r.log.Error().Stack().Err(err).Msg("action.toggleEnabled: error executing query") return err } - log.Debug().Msgf("action.toggleEnabled: %v", actionID) + r.log.Debug().Msgf("action.toggleEnabled: %v", actionID) return nil } diff --git a/internal/database/database.go b/internal/database/database.go index 7fbbea0..80869f3 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -6,13 +6,14 @@ import ( "fmt" "sync" - sq "github.com/Masterminds/squirrel" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" + + sq "github.com/Masterminds/squirrel" ) type DB struct { + log logger.Logger handler *sql.DB lock sync.RWMutex ctx context.Context @@ -24,10 +25,11 @@ type DB struct { squirrel sq.StatementBuilderType } -func NewDB(cfg domain.Config) (*DB, error) { +func NewDB(cfg *domain.Config, log logger.Logger) (*DB, error) { db := &DB{ // set default placeholder for squirrel to support both sqlite and postgres squirrel: sq.StatementBuilder.PlaceholderFormat(sq.Dollar), + log: log, } db.ctx, db.cancel = context.WithCancel(context.Background()) @@ -58,12 +60,12 @@ func (db *DB) Open() error { switch db.Driver { case "sqlite": if err = db.openSQLite(); err != nil { - log.Fatal().Err(err).Msg("could not open sqlite db connection") + db.log.Fatal().Err(err).Msg("could not open sqlite db connection") return err } case "postgres": if err = db.openPostgres(); err != nil { - log.Fatal().Err(err).Msg("could not open postgres db connection") + db.log.Fatal().Err(err).Msg("could not open postgres db connection") return err } } diff --git a/internal/database/download_client.go b/internal/database/download_client.go index 232cbdd..62697e2 100644 --- a/internal/database/download_client.go +++ b/internal/database/download_client.go @@ -6,11 +6,11 @@ import ( "sync" "github.com/autobrr/autobrr/internal/domain" - - "github.com/rs/zerolog/log" + "github.com/autobrr/autobrr/internal/logger" ) type DownloadClientRepo struct { + log logger.Logger db *DB cache *clientCache } @@ -48,8 +48,9 @@ func (c *clientCache) Pop(id int) { c.mu.Unlock() } -func NewDownloadClientRepo(db *DB) domain.DownloadClientRepo { +func NewDownloadClientRepo(log logger.Logger, db *DB) domain.DownloadClientRepo { return &DownloadClientRepo{ + log: log, db: db, cache: NewClientCache(), } @@ -76,13 +77,13 @@ func (r *DownloadClientRepo) List(ctx context.Context) ([]domain.DownloadClient, query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("download_client.list: error building query") + r.log.Error().Stack().Err(err).Msg("download_client.list: error building query") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("download_client.list: error executing query") + r.log.Error().Stack().Err(err).Msg("download_client.list: error executing query") return nil, err } @@ -93,13 +94,13 @@ func (r *DownloadClientRepo) List(ctx context.Context) ([]domain.DownloadClient, var settingsJsonStr string if err := rows.Scan(&f.ID, &f.Name, &f.Type, &f.Enabled, &f.Host, &f.Port, &f.TLS, &f.TLSSkipVerify, &f.Username, &f.Password, &settingsJsonStr); err != nil { - log.Error().Stack().Err(err).Msg("download_client.list: error scanning row") + r.log.Error().Stack().Err(err).Msg("download_client.list: error scanning row") return clients, err } if settingsJsonStr != "" { if err := json.Unmarshal([]byte(settingsJsonStr), &f.Settings); err != nil { - log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr) + r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr) return clients, err } } @@ -107,7 +108,7 @@ func (r *DownloadClientRepo) List(ctx context.Context) ([]domain.DownloadClient, clients = append(clients, f) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("download_client.list: row error") + r.log.Error().Stack().Err(err).Msg("download_client.list: row error") return clients, err } @@ -140,13 +141,13 @@ func (r *DownloadClientRepo) FindByID(ctx context.Context, id int32) (*domain.Do query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("download_client.findByID: error building query") + r.log.Error().Stack().Err(err).Msg("download_client.findByID: error building query") return nil, err } row := r.db.handler.QueryRowContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("download_client.findByID: error executing query") + r.log.Error().Stack().Err(err).Msg("download_client.findByID: error executing query") return nil, err } @@ -154,13 +155,13 @@ func (r *DownloadClientRepo) FindByID(ctx context.Context, id int32) (*domain.Do var settingsJsonStr string if err := row.Scan(&client.ID, &client.Name, &client.Type, &client.Enabled, &client.Host, &client.Port, &client.TLS, &client.TLSSkipVerify, &client.Username, &client.Password, &settingsJsonStr); err != nil { - log.Error().Stack().Err(err).Msg("download_client.findByID: error scanning row") + r.log.Error().Stack().Err(err).Msg("download_client.findByID: error scanning row") return nil, err } if settingsJsonStr != "" { if err := json.Unmarshal([]byte(settingsJsonStr), &client.Settings); err != nil { - log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr) + r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settingsJsonStr) return nil, err } } @@ -179,7 +180,7 @@ func (r *DownloadClientRepo) Store(ctx context.Context, client domain.DownloadCl settingsJson, err := json.Marshal(&settings) if err != nil { - log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings) + r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings) return nil, err } @@ -194,13 +195,13 @@ func (r *DownloadClientRepo) Store(ctx context.Context, client domain.DownloadCl err = queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("download_client.store: error executing query") + r.log.Error().Stack().Err(err).Msg("download_client.store: error executing query") return nil, err } client.ID = retID - log.Debug().Msgf("download_client.store: %d", client.ID) + r.log.Debug().Msgf("download_client.store: %d", client.ID) // save to cache r.cache.Set(client.ID, &client) @@ -219,7 +220,7 @@ func (r *DownloadClientRepo) Update(ctx context.Context, client domain.DownloadC settingsJson, err := json.Marshal(&settings) if err != nil { - log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings) + r.log.Error().Stack().Err(err).Msgf("could not marshal download client settings %v", settings) return nil, err } @@ -239,17 +240,17 @@ func (r *DownloadClientRepo) Update(ctx context.Context, client domain.DownloadC query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("download_client.update: error building query") + r.log.Error().Stack().Err(err).Msg("download_client.update: error building query") return nil, err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("download_client.update: error querying data") + r.log.Error().Stack().Err(err).Msg("download_client.update: error querying data") return nil, err } - log.Debug().Msgf("download_client.update: %d", client.ID) + r.log.Debug().Msgf("download_client.update: %d", client.ID) // save to cache r.cache.Set(client.ID, &client) @@ -264,13 +265,13 @@ func (r *DownloadClientRepo) Delete(ctx context.Context, clientID int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("download_client.delete: error building query") + r.log.Error().Stack().Err(err).Msg("download_client.delete: error building query") return err } res, err := r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("download_client.delete: error query data") + r.log.Error().Stack().Err(err).Msg("download_client.delete: error query data") return err } @@ -282,7 +283,7 @@ func (r *DownloadClientRepo) Delete(ctx context.Context, clientID int) error { return err } - log.Info().Msgf("delete download client: %d", clientID) + r.log.Info().Msgf("delete download client: %d", clientID) return nil } diff --git a/internal/database/feed.go b/internal/database/feed.go index 3528e2f..dadd7fc 100644 --- a/internal/database/feed.go +++ b/internal/database/feed.go @@ -5,19 +5,21 @@ import ( "database/sql" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" sq "github.com/Masterminds/squirrel" - "github.com/rs/zerolog/log" ) -func NewFeedRepo(db *DB) domain.FeedRepo { +func NewFeedRepo(log logger.Logger, db *DB) domain.FeedRepo { return &FeedRepo{ - db: db, + log: log, + db: db, } } type FeedRepo struct { - db *DB + log logger.Logger + db *DB } func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) { @@ -39,13 +41,13 @@ func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feed.FindById: error building query") + r.log.Error().Stack().Err(err).Msg("feed.FindById: error building query") return nil, err } row := r.db.handler.QueryRowContext(ctx, query, args...) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("feed.FindById: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.FindById: error executing query") return nil, err } @@ -54,7 +56,7 @@ func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) { var apiKey sql.NullString if err := row.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &apiKey, &f.CreatedAt, &f.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("feed.FindById: error scanning row") + r.log.Error().Stack().Err(err).Msg("feed.FindById: error scanning row") return nil, err } @@ -83,13 +85,13 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string) query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error building query") + r.log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error building query") return nil, err } row := r.db.handler.QueryRowContext(ctx, query, args...) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error executing query") return nil, err } @@ -98,7 +100,7 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string) var apiKey sql.NullString if err := row.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &apiKey, &f.CreatedAt, &f.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error scanning row") + r.log.Error().Stack().Err(err).Msg("feed.FindByIndexerIdentifier: error scanning row") return nil, err } @@ -127,13 +129,13 @@ func (r *FeedRepo) Find(ctx context.Context) ([]domain.Feed, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feed.Find: error building query") + r.log.Error().Stack().Err(err).Msg("feed.Find: error building query") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("feed.Find: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.Find: error executing query") return nil, err } @@ -146,7 +148,7 @@ func (r *FeedRepo) Find(ctx context.Context) ([]domain.Feed, error) { var apiKey sql.NullString if err := rows.Scan(&f.ID, &f.Indexer, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &apiKey, &f.CreatedAt, &f.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("feed.Find: error scanning row") + r.log.Error().Stack().Err(err).Msg("feed.Find: error scanning row") return nil, err } @@ -187,7 +189,7 @@ func (r *FeedRepo) Store(ctx context.Context, feed *domain.Feed) error { var retID int if err := queryBuilder.QueryRowContext(ctx).Scan(&retID); err != nil { - log.Error().Stack().Err(err).Msg("feed.Store: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.Store: error executing query") return err } @@ -210,13 +212,13 @@ func (r *FeedRepo) Update(ctx context.Context, feed *domain.Feed) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feed.Update: error building query") + r.log.Error().Stack().Err(err).Msg("feed.Update: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("feed.Update: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.Update: error executing query") return err } @@ -234,12 +236,12 @@ func (r *FeedRepo) ToggleEnabled(ctx context.Context, id int, enabled bool) erro query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error building query") + r.log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.ToggleEnabled: error executing query") return err } @@ -253,17 +255,17 @@ func (r *FeedRepo) Delete(ctx context.Context, id int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feed.delete: error building query") + r.log.Error().Stack().Err(err).Msg("feed.delete: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("feed.delete: error executing query") + r.log.Error().Stack().Err(err).Msg("feed.delete: error executing query") return err } - log.Info().Msgf("feed.delete: successfully deleted: %v", id) + r.log.Info().Msgf("feed.delete: successfully deleted: %v", id) return nil } diff --git a/internal/database/feed_cache.go b/internal/database/feed_cache.go index b014bb3..ddca5ef 100644 --- a/internal/database/feed_cache.go +++ b/internal/database/feed_cache.go @@ -4,18 +4,19 @@ import ( "database/sql" "time" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" ) type FeedCacheRepo struct { - db *DB + log logger.Logger + db *DB } -func NewFeedCacheRepo(db *DB) domain.FeedCacheRepo { +func NewFeedCacheRepo(log logger.Logger, db *DB) domain.FeedCacheRepo { return &FeedCacheRepo{ - db: db, + log: log, + db: db, } } @@ -32,13 +33,13 @@ func (r *FeedCacheRepo) Get(bucket string, key string) ([]byte, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feedCache.Get: error building query") + r.log.Error().Stack().Err(err).Msg("feedCache.Get: error building query") return nil, err } row := r.db.handler.QueryRow(query, args...) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("feedCache.Get: query error") + r.log.Error().Stack().Err(err).Msg("feedCache.Get: query error") return nil, err } @@ -46,7 +47,7 @@ func (r *FeedCacheRepo) Get(bucket string, key string) ([]byte, error) { var ttl time.Duration if err := row.Scan(&value, &ttl); err != nil && err != sql.ErrNoRows { - log.Error().Stack().Err(err).Msg("feedCache.Get: error scanning row") + r.log.Error().Stack().Err(err).Msg("feedCache.Get: error scanning row") return nil, err } @@ -64,14 +65,14 @@ func (r *FeedCacheRepo) Exists(bucket string, key string) (bool, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feedCache.Exists: error building query") + r.log.Error().Stack().Err(err).Msg("feedCache.Exists: error building query") return false, err } var exists bool err = r.db.handler.QueryRow(query, args...).Scan(&exists) if err != nil && err != sql.ErrNoRows { - log.Error().Stack().Err(err).Msg("feedCache.Exists: query error") + r.log.Error().Stack().Err(err).Msg("feedCache.Exists: query error") } return exists, nil @@ -85,12 +86,12 @@ func (r *FeedCacheRepo) Put(bucket string, key string, val []byte, ttl time.Time query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("feedCache.Put: error building query") + r.log.Error().Stack().Err(err).Msg("feedCache.Put: error building query") return err } if _, err = r.db.handler.Exec(query, args...); err != nil { - log.Error().Stack().Err(err).Msg("feedCache.Put: error executing query") + r.log.Error().Stack().Err(err).Msg("feedCache.Put: error executing query") return err } diff --git a/internal/database/filter.go b/internal/database/filter.go index 25b8288..aa825ae 100644 --- a/internal/database/filter.go +++ b/internal/database/filter.go @@ -5,19 +5,23 @@ import ( "database/sql" "time" + "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" + sq "github.com/Masterminds/squirrel" "github.com/lib/pq" - "github.com/rs/zerolog/log" - - "github.com/autobrr/autobrr/internal/domain" ) type FilterRepo struct { - db *DB + log logger.Logger + db *DB } -func NewFilterRepo(db *DB) domain.FilterRepo { - return &FilterRepo{db: db} +func NewFilterRepo(log logger.Logger, db *DB) domain.FilterRepo { + return &FilterRepo{ + log: log, + db: db, + } } func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) { @@ -36,13 +40,13 @@ func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.list: error building query") + r.log.Error().Stack().Err(err).Msg("filter.list: error building query") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.list: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.list: error executing query") return nil, err } @@ -55,7 +59,7 @@ func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) { var matchReleases, exceptReleases sql.NullString if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &matchReleases, &exceptReleases, &f.CreatedAt, &f.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("filter.list: error scanning row") + r.log.Error().Stack().Err(err).Msg("filter.list: error scanning row") return nil, err } @@ -65,7 +69,7 @@ func (r *FilterRepo) ListFilters(ctx context.Context) ([]domain.Filter, error) { filters = append(filters, f) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("filter.list: row error") + r.log.Error().Stack().Err(err).Msg("filter.list: row error") return nil, err } @@ -129,13 +133,13 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.findByID: error building query") + r.log.Error().Stack().Err(err).Msg("filter.findByID: error building query") return nil, err } row := r.db.handler.QueryRowContext(ctx, query, args...) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("filter.findByID: error query row") + r.log.Error().Stack().Err(err).Msg("filter.findByID: error query row") return nil, err } @@ -145,7 +149,7 @@ func (r *FilterRepo) FindByID(ctx context.Context, filterID int) (*domain.Filter var delay, maxDownloads, logScore sql.NullInt32 if err := row.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &f.CreatedAt, &f.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msgf("filter.findByID: %v : error scanning row", filterID) + r.log.Error().Stack().Err(err).Msgf("filter.findByID: %v : error scanning row", filterID) return nil, err } @@ -269,13 +273,13 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error building query") + r.log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error building query") return nil, err } rows, err := tx.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error executing query") return nil, err } @@ -290,7 +294,7 @@ func (r *FilterRepo) findByIndexerIdentifier(ctx context.Context, tx *Tx, indexe var delay, maxDownloads, logScore sql.NullInt32 if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &minSize, &maxSize, &delay, &f.Priority, &maxDownloads, &maxDownloadsUnit, &matchReleases, &exceptReleases, &useRegex, &matchReleaseGroups, &exceptReleaseGroups, &scene, &freeleech, &freeleechPercent, &shows, &seasons, &episodes, pq.Array(&f.Resolutions), pq.Array(&f.Codecs), pq.Array(&f.Sources), pq.Array(&f.Containers), pq.Array(&f.MatchHDR), pq.Array(&f.ExceptHDR), pq.Array(&f.MatchOther), pq.Array(&f.ExceptOther), &years, &artists, &albums, pq.Array(&f.MatchReleaseTypes), pq.Array(&f.Formats), pq.Array(&f.Quality), pq.Array(&f.Media), &logScore, &hasLog, &hasCue, &perfectFlac, &matchCategories, &exceptCategories, &matchUploaders, &exceptUploaders, &tags, &exceptTags, pq.Array(&f.Origins), &f.CreatedAt, &f.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error scanning row") + r.log.Error().Stack().Err(err).Msg("filter.findByIndexerIdentifier: error scanning row") return nil, err } @@ -434,7 +438,7 @@ func (r *FilterRepo) Store(ctx context.Context, filter domain.Filter) (*domain.F err := queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("filter.store: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.store: error executing query") return nil, err } @@ -498,13 +502,13 @@ func (r *FilterRepo) Update(ctx context.Context, filter domain.Filter) (*domain. query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.update: error building query") + r.log.Error().Stack().Err(err).Msg("filter.update: error building query") return nil, err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.update: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.update: error executing query") return nil, err } @@ -522,12 +526,12 @@ func (r *FilterRepo) ToggleEnabled(ctx context.Context, filterID int, enabled bo query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error building query") + r.log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.toggleEnabled: error executing query") return err } @@ -548,12 +552,12 @@ func (r *FilterRepo) StoreIndexerConnections(ctx context.Context, filterID int, deleteQuery, deleteArgs, err := deleteQueryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query") + r.log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query") return err } _, err = tx.ExecContext(ctx, deleteQuery, deleteArgs...) if err != nil { - log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error deleting indexers for filter: %v", filterID) + r.log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error deleting indexers for filter: %v", filterID) return err } @@ -564,21 +568,21 @@ func (r *FilterRepo) StoreIndexerConnections(ctx context.Context, filterID int, query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query") + r.log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error building query") return err } _, err = tx.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.StoreIndexerConnections: error executing query") return err } - log.Debug().Msgf("filter.StoreIndexerConnections: store '%v' on filter: %v", indexer.Name, filterID) + r.log.Debug().Msgf("filter.StoreIndexerConnections: store '%v' on filter: %v", indexer.Name, filterID) } err = tx.Commit() if err != nil { - log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error storing indexers for filter: %v", filterID) + r.log.Error().Stack().Err(err).Msgf("filter.StoreIndexerConnections: error storing indexers for filter: %v", filterID) return err } @@ -592,13 +596,13 @@ func (r *FilterRepo) StoreIndexerConnection(ctx context.Context, filterID int, i query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error building query") + r.log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.storeIndexerConnection: error executing query") return err } @@ -612,13 +616,13 @@ func (r *FilterRepo) DeleteIndexerConnections(ctx context.Context, filterID int) query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error building query") + r.log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.deleteIndexerConnections: error executing query") return err } @@ -632,17 +636,17 @@ func (r *FilterRepo) Delete(ctx context.Context, filterID int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("filter.delete: error building query") + r.log.Error().Stack().Err(err).Msg("filter.delete: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("filter.delete: error executing query") + r.log.Error().Stack().Err(err).Msg("filter.delete: error executing query") return err } - log.Info().Msgf("filter.delete: successfully deleted: %v", filterID) + r.log.Info().Msgf("filter.delete: successfully deleted: %v", filterID) return nil } @@ -667,14 +671,14 @@ WHERE "release".filter_id = ?;` row := tx.QueryRowContext(ctx, query, filterID) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error querying stats") + r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error querying stats") return nil, err } var f domain.FilterDownloads if err := row.Scan(&f.HourCount, &f.DayCount, &f.WeekCount, &f.MonthCount, &f.TotalCount); err != nil { - log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error scanning stats data to struct") + r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterSqlite: error scanning stats data to struct") return nil, err } @@ -693,14 +697,14 @@ WHERE "release".filter_id = ?;` row := tx.QueryRowContext(ctx, query, filterID) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error querying stats") + r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error querying stats") return nil, err } var f domain.FilterDownloads if err := row.Scan(&f.HourCount, &f.DayCount, &f.WeekCount, &f.MonthCount, &f.TotalCount); err != nil { - log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error scanning stats data to struct") + r.log.Error().Stack().Err(err).Msg("filter.downloadsByFilterPostgres: error scanning stats data to struct") return nil, err } diff --git a/internal/database/indexer.go b/internal/database/indexer.go index 9b27a8c..d1dbc3e 100644 --- a/internal/database/indexer.go +++ b/internal/database/indexer.go @@ -6,25 +6,26 @@ import ( "encoding/json" "time" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" ) type IndexerRepo struct { - db *DB + log logger.Logger + db *DB } -func NewIndexerRepo(db *DB) domain.IndexerRepo { +func NewIndexerRepo(log logger.Logger, db *DB) domain.IndexerRepo { return &IndexerRepo{ - db: db, + log: log, + db: db, } } func (r *IndexerRepo) Store(ctx context.Context, indexer domain.Indexer) (*domain.Indexer, error) { settings, err := json.Marshal(indexer.Settings) if err != nil { - log.Error().Stack().Err(err).Msg("error marshaling json data") + r.log.Error().Stack().Err(err).Msg("error marshaling json data") return nil, err } @@ -38,7 +39,7 @@ func (r *IndexerRepo) Store(ctx context.Context, indexer domain.Indexer) (*domai err = queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("indexer.store: error executing query") + r.log.Error().Stack().Err(err).Msg("indexer.store: error executing query") return nil, err } @@ -50,7 +51,7 @@ func (r *IndexerRepo) Store(ctx context.Context, indexer domain.Indexer) (*domai func (r *IndexerRepo) Update(ctx context.Context, indexer domain.Indexer) (*domain.Indexer, error) { settings, err := json.Marshal(indexer.Settings) if err != nil { - log.Error().Stack().Err(err).Msg("error marshaling json data") + r.log.Error().Stack().Err(err).Msg("error marshaling json data") return nil, err } @@ -64,13 +65,13 @@ func (r *IndexerRepo) Update(ctx context.Context, indexer domain.Indexer) (*doma query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("indexer.update: error building query") + r.log.Error().Stack().Err(err).Msg("indexer.update: error building query") return nil, err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("indexer.update: error executing query") + r.log.Error().Stack().Err(err).Msg("indexer.update: error executing query") return nil, err } @@ -80,7 +81,7 @@ func (r *IndexerRepo) Update(ctx context.Context, indexer domain.Indexer) (*doma func (r *IndexerRepo) List(ctx context.Context) ([]domain.Indexer, error) { rows, err := r.db.handler.QueryContext(ctx, "SELECT id, enabled, name, identifier, implementation, settings FROM indexer ORDER BY name ASC") if err != nil { - log.Error().Stack().Err(err).Msg("indexer.list: error query indexer") + r.log.Error().Stack().Err(err).Msg("indexer.list: error query indexer") return nil, err } @@ -95,7 +96,7 @@ func (r *IndexerRepo) List(ctx context.Context) ([]domain.Indexer, error) { var settingsMap map[string]string if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &f.Identifier, &implementation, &settings); err != nil { - log.Error().Stack().Err(err).Msg("indexer.list: error scanning data to struct") + r.log.Error().Stack().Err(err).Msg("indexer.list: error scanning data to struct") return nil, err } @@ -103,7 +104,7 @@ func (r *IndexerRepo) List(ctx context.Context) ([]domain.Indexer, error) { err = json.Unmarshal([]byte(settings), &settingsMap) if err != nil { - log.Error().Stack().Err(err).Msg("indexer.list: error unmarshal settings") + r.log.Error().Stack().Err(err).Msg("indexer.list: error unmarshal settings") return nil, err } @@ -127,13 +128,13 @@ func (r *IndexerRepo) FindByFilterID(ctx context.Context, id int) ([]domain.Inde query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.check_existing_network: error fetching data") + r.log.Error().Stack().Err(err).Msg("irc.check_existing_network: error fetching data") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error query indexer") + r.log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error query indexer") return nil, err } @@ -147,13 +148,13 @@ func (r *IndexerRepo) FindByFilterID(ctx context.Context, id int) ([]domain.Inde var settingsMap map[string]string if err := rows.Scan(&f.ID, &f.Enabled, &f.Name, &f.Identifier, &settings); err != nil { - log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error scanning data to struct") + r.log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error scanning data to struct") return nil, err } err = json.Unmarshal([]byte(settings), &settingsMap) if err != nil { - log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error unmarshal settings") + r.log.Error().Stack().Err(err).Msg("indexer.find_by_filter_id: error unmarshal settings") return nil, err } @@ -176,17 +177,17 @@ func (r *IndexerRepo) Delete(ctx context.Context, id int) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("indexer.delete: error building query") + r.log.Error().Stack().Err(err).Msg("indexer.delete: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msgf("indexer.delete: error executing query: '%v'", query) + r.log.Error().Stack().Err(err).Msgf("indexer.delete: error executing query: '%v'", query) return err } - log.Debug().Msgf("indexer.delete: id %v", id) + r.log.Debug().Msgf("indexer.delete: id %v", id) return nil } diff --git a/internal/database/irc.go b/internal/database/irc.go index e12478a..88659db 100644 --- a/internal/database/irc.go +++ b/internal/database/irc.go @@ -3,20 +3,24 @@ package database import ( "context" "database/sql" - "github.com/pkg/errors" "time" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" - "github.com/rs/zerolog/log" + "github.com/pkg/errors" ) type IrcRepo struct { - db *DB + log logger.Logger + db *DB } -func NewIrcRepo(db *DB) domain.IrcRepo { - return &IrcRepo{db: db} +func NewIrcRepo(log logger.Logger, db *DB) domain.IrcRepo { + return &IrcRepo{ + log: log, + db: db, + } } func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetwork, error) { @@ -27,10 +31,10 @@ func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error building query") + r.log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error building query") return nil, err } - log.Trace().Str("database", "irc.check_existing_network").Msgf("query: '%v', args: '%v'", query, args) + r.log.Trace().Str("database", "irc.check_existing_network").Msgf("query: '%v', args: '%v'", query, args) var n domain.IrcNetwork @@ -40,7 +44,7 @@ func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw row := r.db.handler.QueryRowContext(ctx, query, args...) if err := row.Scan(&n.ID, &n.Enabled, &n.Name, &n.Server, &n.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil { - log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.getNetworkByID: error executing query") return nil, err } @@ -67,13 +71,13 @@ func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query") + r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query") return err } _, err = tx.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query") return err } @@ -83,19 +87,19 @@ func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error { netQuery, netArgs, err := netQueryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query") + r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error building query") return err } _, err = tx.ExecContext(ctx, netQuery, netArgs...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.deleteNetwork: error executing query") return err } err = tx.Commit() if err != nil { - log.Error().Stack().Err(err).Msgf("irc.deleteNetwork: error deleting network %v", id) + r.log.Error().Stack().Err(err).Msgf("irc.deleteNetwork: error deleting network %v", id) return err } @@ -111,13 +115,13 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork, query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error building query") + r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error building query") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error executing query") return nil, err } @@ -132,7 +136,7 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork, var tls sql.NullBool if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil { - log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error scanning row") + r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: error scanning row") return nil, err } @@ -146,7 +150,7 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork, networks = append(networks, net) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: row error") + r.log.Error().Stack().Err(err).Msg("irc.findActiveNetworks: row error") return nil, err } @@ -161,13 +165,13 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.listNetworks: error building query") + r.log.Error().Stack().Err(err).Msg("irc.listNetworks: error building query") return nil, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.listNetworks: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.listNetworks: error executing query") return nil, err } @@ -182,7 +186,7 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) var tls sql.NullBool if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil { - log.Error().Stack().Err(err).Msg("irc.listNetworks: error scanning row") + r.log.Error().Stack().Err(err).Msg("irc.listNetworks: error scanning row") return nil, err } @@ -196,7 +200,7 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) networks = append(networks, net) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("irc.listNetworks: row error") + r.log.Error().Stack().Err(err).Msg("irc.listNetworks: row error") return nil, err } @@ -211,13 +215,13 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.listChannels: error building query") + r.log.Error().Stack().Err(err).Msg("irc.listChannels: error building query") return nil, err } rows, err := r.db.handler.Query(query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.listChannels: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.listChannels: error executing query") return nil, err } defer rows.Close() @@ -228,7 +232,7 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) { var pass sql.NullString if err := rows.Scan(&ch.ID, &ch.Name, &ch.Enabled, &pass); err != nil { - log.Error().Stack().Err(err).Msg("irc.listChannels: error scanning row") + r.log.Error().Stack().Err(err).Msg("irc.listChannels: error scanning row") return nil, err } @@ -237,7 +241,7 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) { channels = append(channels, ch) } if err := rows.Err(); err != nil { - log.Error().Stack().Err(err).Msg("irc.listChannels: error row") + r.log.Error().Stack().Err(err).Msg("irc.listChannels: error row") return nil, err } @@ -253,10 +257,10 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error building query") + r.log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error building query") return nil, err } - log.Trace().Str("database", "irc.checkExistingNetwork").Msgf("query: '%v', args: '%v'", query, args) + r.log.Trace().Str("database", "irc.checkExistingNetwork").Msgf("query: '%v', args: '%v'", query, args) row := r.db.handler.QueryRowContext(ctx, query, args...) @@ -270,7 +274,7 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN // no result is not an error in our case return nil, nil } else if err != nil { - log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error scanning data to struct") + r.log.Error().Stack().Err(err).Msg("irc.checkExistingNetwork: error scanning data to struct") return nil, err } @@ -322,7 +326,7 @@ func (r *IrcRepo) StoreNetwork(network *domain.IrcNetwork) error { err = queryBuilder.QueryRow().Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeNetwork: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.storeNetwork: error executing query") return errors.Wrap(err, "error executing query") } @@ -357,14 +361,14 @@ func (r *IrcRepo) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.updateNetwork: error building query") + r.log.Error().Stack().Err(err).Msg("irc.updateNetwork: error building query") return err } // update record _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.updateNetwork: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.updateNetwork: error executing query") return err } @@ -387,13 +391,13 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query") + r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query") return err } _, err = tx.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query") return err } @@ -425,7 +429,7 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha err = channelQueryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query") return errors.Wrap(err, "error executing query") } @@ -433,13 +437,13 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha //channelQuery, channelArgs, err := channelQueryBuilder.ToSql() //if err != nil { - // log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query") + // r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error building query") // return err //} // //res, err = r.db.handler.ExecContext(ctx, channelQuery, channelArgs...) //if err != nil { - // log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query") + // r.log.Error().Stack().Err(err).Msg("irc.storeNetworkChannels: error executing query") // return err //} // @@ -448,7 +452,7 @@ func (r *IrcRepo) StoreNetworkChannels(ctx context.Context, networkID int64, cha err = tx.Commit() if err != nil { - log.Error().Stack().Err(err).Msgf("irc.storeNetworkChannels: error deleting network: %v", networkID) + r.log.Error().Stack().Err(err).Msgf("irc.storeNetworkChannels: error deleting network: %v", networkID) return err } @@ -471,13 +475,13 @@ func (r *IrcRepo) StoreChannel(networkID int64, channel *domain.IrcChannel) erro query, args, err := channelQueryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query") + r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query") return err } _, err = r.db.handler.Exec(query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query") return err } } else { @@ -505,7 +509,7 @@ func (r *IrcRepo) StoreChannel(networkID int64, channel *domain.IrcChannel) erro err = queryBuilder.QueryRow().Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("irc.storeChannels: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.storeChannels: error executing query") return errors.Wrap(err, "error executing query") } @@ -513,13 +517,13 @@ func (r *IrcRepo) StoreChannel(networkID int64, channel *domain.IrcChannel) erro //channelQuery, channelArgs, err := channelQueryBuilder.ToSql() //if err != nil { - // log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query") + // r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error building query") // return err //} // //res, err := r.db.handler.Exec(channelQuery, channelArgs...) //if err != nil { - // log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query") + // r.log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query") // return errors.Wrap(err, "error executing query") // //return err //} @@ -544,13 +548,13 @@ func (r *IrcRepo) UpdateChannel(channel *domain.IrcChannel) error { query, args, err := channelQueryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("irc.updateChannel: error building query") + r.log.Error().Stack().Err(err).Msg("irc.updateChannel: error building query") return err } _, err = r.db.handler.Exec(query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("irc.updateChannel: error executing query") + r.log.Error().Stack().Err(err).Msg("irc.updateChannel: error executing query") return err } diff --git a/internal/database/notification.go b/internal/database/notification.go index ccab294..1a3c23e 100644 --- a/internal/database/notification.go +++ b/internal/database/notification.go @@ -3,20 +3,23 @@ package database import ( "context" "database/sql" + "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" sq "github.com/Masterminds/squirrel" "github.com/lib/pq" - "github.com/rs/zerolog/log" ) type NotificationRepo struct { - db *DB + log logger.Logger + db *DB } -func NewNotificationRepo(db *DB) domain.NotificationRepo { +func NewNotificationRepo(log logger.Logger, db *DB) domain.NotificationRepo { return &NotificationRepo{ - db: db, + log: log, + db: db, } } @@ -29,13 +32,13 @@ func (r *NotificationRepo) Find(ctx context.Context, params domain.NotificationQ query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("notification.find: error building query") + r.log.Error().Stack().Err(err).Msg("notification.find: error building query") return nil, 0, err } rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("notification.find: error executing query") + r.log.Error().Stack().Err(err).Msg("notification.find: error executing query") return nil, 0, err } @@ -51,7 +54,7 @@ func (r *NotificationRepo) Find(ctx context.Context, params domain.NotificationQ //if err := rows.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.CreatedAt, &n.UpdatedAt); err != nil { //var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices sql.NullString if err := rows.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &webhook, &n.CreatedAt, &n.UpdatedAt, &totalCount); err != nil { - log.Error().Stack().Err(err).Msg("notification.find: error scanning row") + r.log.Error().Stack().Err(err).Msg("notification.find: error scanning row") return nil, 0, err } @@ -87,7 +90,7 @@ func (r *NotificationRepo) List(ctx context.Context) ([]domain.Notification, err rows, err := r.db.handler.QueryContext(ctx, "SELECT id, name, type, enabled, events, token, api_key, webhook, title, icon, host, username, password, channel, targets, devices, created_at, updated_at FROM notification ORDER BY name ASC") if err != nil { - log.Error().Stack().Err(err).Msg("filters_list: error query data") + r.log.Error().Stack().Err(err).Msg("filters_list: error query data") return nil, err } @@ -100,7 +103,7 @@ func (r *NotificationRepo) List(ctx context.Context) ([]domain.Notification, err var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices sql.NullString if err := rows.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.CreatedAt, &n.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("notification_list: error scanning data to struct") + r.log.Error().Stack().Err(err).Msg("notification_list: error scanning data to struct") return nil, err } @@ -144,7 +147,7 @@ func (r *NotificationRepo) FindByID(ctx context.Context, id int) (*domain.Notifi query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("notification.findByID: error building query") + r.log.Error().Stack().Err(err).Msg("notification.findByID: error building query") return nil, err } @@ -158,7 +161,7 @@ func (r *NotificationRepo) FindByID(ctx context.Context, id int) (*domain.Notifi var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices sql.NullString if err := row.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.CreatedAt, &n.UpdatedAt); err != nil { - log.Error().Stack().Err(err).Msg("notification.findByID: error scanning row") + r.log.Error().Stack().Err(err).Msg("notification.findByID: error scanning row") return nil, err } @@ -203,11 +206,11 @@ func (r *NotificationRepo) Store(ctx context.Context, notification domain.Notifi err := queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("notification.store: error executing query") + r.log.Error().Stack().Err(err).Msg("notification.store: error executing query") return nil, err } - log.Debug().Msgf("notification.store: added new %v", retID) + r.log.Debug().Msgf("notification.store: added new %v", retID) notification.ID = int(retID) return ¬ification, nil @@ -228,17 +231,17 @@ func (r *NotificationRepo) Update(ctx context.Context, notification domain.Notif query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("action.update: error building query") + r.log.Error().Stack().Err(err).Msg("action.update: error building query") return nil, err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("notification.update: error executing query") + r.log.Error().Stack().Err(err).Msg("notification.update: error executing query") return nil, err } - log.Debug().Msgf("notification.update: %v", notification.Name) + r.log.Debug().Msgf("notification.update: %v", notification.Name) return ¬ification, nil } @@ -250,17 +253,17 @@ func (r *NotificationRepo) Delete(ctx context.Context, notificationID int) error query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("notification.delete: error building query") + r.log.Error().Stack().Err(err).Msg("notification.delete: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("notification.delete: error executing query") + r.log.Error().Stack().Err(err).Msg("notification.delete: error executing query") return err } - log.Info().Msgf("notification.delete: successfully deleted: %v", notificationID) + r.log.Info().Msgf("notification.delete: successfully deleted: %v", notificationID) return nil } diff --git a/internal/database/postgres.go b/internal/database/postgres.go index 72d8938..22de5dc 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -6,7 +6,6 @@ import ( "fmt" _ "github.com/lib/pq" - "github.com/rs/zerolog/log" ) func (db *DB) openPostgres() error { @@ -14,19 +13,19 @@ func (db *DB) openPostgres() error { // open database connection if db.handler, err = sql.Open("postgres", db.DSN); err != nil { - log.Fatal().Err(err).Msg("could not open postgres connection") + db.log.Fatal().Err(err).Msg("could not open postgres connection") return err } err = db.handler.Ping() if err != nil { - log.Fatal().Err(err).Msg("could not ping postgres database") + db.log.Fatal().Err(err).Msg("could not ping postgres database") return err } // migrate db if err = db.migratePostgres(); err != nil { - log.Fatal().Err(err).Msg("could not migrate postgres database") + db.log.Fatal().Err(err).Msg("could not migrate postgres database") return err } diff --git a/internal/database/release.go b/internal/database/release.go index 9a11847..bd1da3f 100644 --- a/internal/database/release.go +++ b/internal/database/release.go @@ -5,18 +5,23 @@ import ( "database/sql" "strings" - sq "github.com/Masterminds/squirrel" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" + + sq "github.com/Masterminds/squirrel" "github.com/lib/pq" - "github.com/rs/zerolog/log" ) type ReleaseRepo struct { - db *DB + log logger.Logger + db *DB } -func NewReleaseRepo(db *DB) domain.ReleaseRepo { - return &ReleaseRepo{db: db} +func NewReleaseRepo(log logger.Logger, db *DB) domain.ReleaseRepo { + return &ReleaseRepo{ + log: log, + db: db, + } } func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) (*domain.Release, error) { @@ -34,13 +39,13 @@ func (repo *ReleaseRepo) Store(ctx context.Context, r *domain.Release) (*domain. err := queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("release.store: error executing query") + repo.log.Error().Stack().Err(err).Msg("release.store: error executing query") return nil, err } r.ID = retID - log.Debug().Msgf("release.store: %+v", r) + repo.log.Debug().Msgf("release.store: %+v", r) return r, nil } @@ -57,13 +62,13 @@ func (repo *ReleaseRepo) StoreReleaseActionStatus(ctx context.Context, a *domain query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("release.store: error building query") + repo.log.Error().Stack().Err(err).Msg("release.store: error building query") return err } _, err = repo.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("error updating status of release") + repo.log.Error().Stack().Err(err).Msg("error updating status of release") return err } @@ -79,14 +84,14 @@ func (repo *ReleaseRepo) StoreReleaseActionStatus(ctx context.Context, a *domain err := queryBuilder.QueryRowContext(ctx).Scan(&retID) if err != nil { - log.Error().Stack().Err(err).Msg("release.storeReleaseActionStatus: error executing query") + repo.log.Error().Stack().Err(err).Msg("release.storeReleaseActionStatus: error executing query") return err } a.ID = retID } - log.Trace().Msgf("release.store_release_action_status: %+v", a) + repo.log.Trace().Msgf("release.store_release_action_status: %+v", a) return nil } @@ -148,20 +153,20 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain } query, args, err := queryBuilder.ToSql() - log.Trace().Str("database", "release.find").Msgf("query: '%v', args: '%v'", query, args) + repo.log.Trace().Str("database", "release.find").Msgf("query: '%v', args: '%v'", query, args) res := make([]*domain.Release, 0) rows, err := tx.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("error fetching releases") + repo.log.Error().Stack().Err(err).Msg("error fetching releases") return res, 0, 0, nil } defer rows.Close() if err := rows.Err(); err != nil { - log.Error().Stack().Err(err) + repo.log.Error().Stack().Err(err) return res, 0, 0, err } @@ -173,7 +178,7 @@ func (repo *ReleaseRepo) findReleases(ctx context.Context, tx *Tx, params domain var indexer, filter sql.NullString if err := rows.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &indexer, &filter, &rls.Protocol, &rls.Title, &rls.TorrentName, &rls.Size, &rls.Timestamp, &countItems); err != nil { - log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") + repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") return res, 0, 0, err } @@ -196,20 +201,20 @@ func (repo *ReleaseRepo) GetIndexerOptions(ctx context.Context) ([]string, error query := `SELECT DISTINCT indexer FROM "release" UNION SELECT DISTINCT identifier indexer FROM indexer;` - log.Trace().Str("database", "release.get_indexers").Msgf("query: '%v'", query) + repo.log.Trace().Str("database", "release.get_indexers").Msgf("query: '%v'", query) res := make([]string, 0) rows, err := repo.db.handler.QueryContext(ctx, query) if err != nil { - log.Error().Stack().Err(err).Msg("error fetching indexer list") + repo.log.Error().Stack().Err(err).Msg("error fetching indexer list") return res, err } defer rows.Close() if err := rows.Err(); err != nil { - log.Error().Stack().Err(err) + repo.log.Error().Stack().Err(err) return res, err } @@ -217,7 +222,7 @@ func (repo *ReleaseRepo) GetIndexerOptions(ctx context.Context) ([]string, error var indexer string if err := rows.Scan(&indexer); err != nil { - log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") + repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") return res, err } @@ -240,14 +245,14 @@ func (repo *ReleaseRepo) GetActionStatusByReleaseID(ctx context.Context, release rows, err := repo.db.handler.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("error fetching releases") + repo.log.Error().Stack().Err(err).Msg("error fetching releases") return res, nil } defer rows.Close() if err := rows.Err(); err != nil { - log.Error().Stack().Err(err) + repo.log.Error().Stack().Err(err) return res, err } @@ -255,7 +260,7 @@ func (repo *ReleaseRepo) GetActionStatusByReleaseID(ctx context.Context, release var rls domain.ReleaseActionStatus if err := rows.Scan(&rls.ID, &rls.Status, &rls.Action, &rls.Type, pq.Array(&rls.Rejections), &rls.Timestamp); err != nil { - log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") + repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") return res, err } @@ -278,14 +283,14 @@ func (repo *ReleaseRepo) attachActionStatus(ctx context.Context, tx *Tx, release rows, err := tx.QueryContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("error fetching releases") + repo.log.Error().Stack().Err(err).Msg("error fetching releases") return res, nil } defer rows.Close() if err := rows.Err(); err != nil { - log.Error().Stack().Err(err) + repo.log.Error().Stack().Err(err) return res, err } @@ -293,7 +298,7 @@ func (repo *ReleaseRepo) attachActionStatus(ctx context.Context, tx *Tx, release var rls domain.ReleaseActionStatus if err := rows.Scan(&rls.ID, &rls.Status, &rls.Action, &rls.Type, pq.Array(&rls.Rejections), &rls.Timestamp); err != nil { - log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") + repo.log.Error().Stack().Err(err).Msg("release.find: error scanning data to struct") return res, err } @@ -316,14 +321,14 @@ FROM "release";` row := repo.db.handler.QueryRowContext(ctx, query) if err := row.Err(); err != nil { - log.Error().Stack().Err(err).Msg("release.stats: error querying stats") + repo.log.Error().Stack().Err(err).Msg("release.stats: error querying stats") return nil, err } var rls domain.ReleaseStats if err := row.Scan(&rls.TotalCount, &rls.FilteredCount, &rls.FilterRejectedCount, &rls.PushApprovedCount, &rls.PushRejectedCount); err != nil { - log.Error().Stack().Err(err).Msg("release.stats: error scanning stats data to struct") + repo.log.Error().Stack().Err(err).Msg("release.stats: error scanning stats data to struct") return nil, err } @@ -340,19 +345,19 @@ func (repo *ReleaseRepo) Delete(ctx context.Context) error { _, err = tx.ExecContext(ctx, `DELETE FROM "release"`) if err != nil { - log.Error().Stack().Err(err).Msg("error deleting all releases") + repo.log.Error().Stack().Err(err).Msg("error deleting all releases") return err } _, err = tx.ExecContext(ctx, `DELETE FROM release_action_status`) if err != nil { - log.Error().Stack().Err(err).Msg("error deleting all release_action_status") + repo.log.Error().Stack().Err(err).Msg("error deleting all release_action_status") return err } err = tx.Commit() if err != nil { - log.Error().Stack().Err(err).Msg("error deleting all releases") + repo.log.Error().Stack().Err(err).Msg("error deleting all releases") return err } diff --git a/internal/database/sqlite.go b/internal/database/sqlite.go index e5f6b3c..15bcd3c 100644 --- a/internal/database/sqlite.go +++ b/internal/database/sqlite.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/lib/pq" - "github.com/rs/zerolog/log" _ "modernc.org/sqlite" ) @@ -18,7 +17,7 @@ func (db *DB) openSQLite() error { // open database connection if db.handler, err = sql.Open("sqlite", db.DSN+"?_pragma=busy_timeout%3d1000"); err != nil { - log.Fatal().Err(err).Msg("could not open db connection") + db.log.Fatal().Err(err).Msg("could not open db connection") return err } @@ -42,7 +41,7 @@ func (db *DB) openSQLite() error { // migrate db if err = db.migrateSQLite(); err != nil { - log.Fatal().Err(err).Msg("could not migrate db") + db.log.Fatal().Err(err).Msg("could not migrate db") return err } diff --git a/internal/database/user.go b/internal/database/user.go index 148b290..c0a54d8 100644 --- a/internal/database/user.go +++ b/internal/database/user.go @@ -2,17 +2,20 @@ package database import ( "context" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" ) type UserRepo struct { - db *DB + log logger.Logger + db *DB } -func NewUserRepo(db *DB) domain.UserRepo { - return &UserRepo{db: db} +func NewUserRepo(log logger.Logger, db *DB) domain.UserRepo { + return &UserRepo{ + log: log, + db: db, + } } func (r *UserRepo) GetUserCount(ctx context.Context) (int, error) { @@ -20,7 +23,7 @@ func (r *UserRepo) GetUserCount(ctx context.Context) (int, error) { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("user.store: error building query") + r.log.Error().Stack().Err(err).Msg("user.store: error building query") return 0, err } @@ -31,7 +34,7 @@ func (r *UserRepo) GetUserCount(ctx context.Context) (int, error) { result := 0 if err := row.Scan(&result); err != nil { - log.Error().Err(err).Msg("could not query number of users") + r.log.Error().Err(err).Msg("could not query number of users") return 0, err } @@ -47,7 +50,7 @@ func (r *UserRepo) FindByUsername(ctx context.Context, username string) (*domain query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("user.store: error building query") + r.log.Error().Stack().Err(err).Msg("user.store: error building query") return nil, err } @@ -59,7 +62,7 @@ func (r *UserRepo) FindByUsername(ctx context.Context, username string) (*domain var user domain.User if err := row.Scan(&user.ID, &user.Username, &user.Password); err != nil { - log.Error().Err(err).Msg("could not scan user to struct") + r.log.Error().Err(err).Msg("could not scan user to struct") return nil, err } @@ -77,13 +80,13 @@ func (r *UserRepo) Store(ctx context.Context, user domain.User) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("user.store: error building query") + r.log.Error().Stack().Err(err).Msg("user.store: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("user.store: error executing query") + r.log.Error().Stack().Err(err).Msg("user.store: error executing query") return err } @@ -102,13 +105,13 @@ func (r *UserRepo) Update(ctx context.Context, user domain.User) error { query, args, err := queryBuilder.ToSql() if err != nil { - log.Error().Stack().Err(err).Msg("user.store: error building query") + r.log.Error().Stack().Err(err).Msg("user.store: error building query") return err } _, err = r.db.handler.ExecContext(ctx, query, args...) if err != nil { - log.Error().Stack().Err(err).Msg("user.store: error executing query") + r.log.Error().Stack().Err(err).Msg("user.store: error executing query") return err } diff --git a/internal/domain/config.go b/internal/domain/config.go index 9e69ea4..ff615bd 100644 --- a/internal/domain/config.go +++ b/internal/domain/config.go @@ -1,6 +1,7 @@ package domain type Config struct { + Version string ConfigPath string Host string `toml:"host"` Port int `toml:"port"` diff --git a/internal/domain/indexer.go b/internal/domain/indexer.go index feae247..9da1751 100644 --- a/internal/domain/indexer.go +++ b/internal/domain/indexer.go @@ -3,11 +3,11 @@ package domain import ( "bytes" "context" + "errors" "net/url" "text/template" "github.com/dustin/go-humanize" - "github.com/rs/zerolog/log" ) type IndexerRepo interface { @@ -148,15 +148,13 @@ func (p *IndexerParse) ParseTorrentUrl(vars map[string]string, extraVars map[str // setup text template to inject variables into tmpl, err := template.New("torrenturl").Parse(p.Match.TorrentURL) if err != nil { - log.Error().Err(err).Msg("could not create torrent url template") - return err + return errors.New("could not create torrent url template") } var urlBytes bytes.Buffer err = tmpl.Execute(&urlBytes, &tmpVars) if err != nil { - log.Error().Err(err).Msg("could not write torrent url template output") - return err + return errors.New("could not write torrent url template output") } release.TorrentURL = urlBytes.String() diff --git a/internal/domain/release.go b/internal/domain/release.go index 021ebd3..dabfbea 100644 --- a/internal/domain/release.go +++ b/internal/domain/release.go @@ -20,7 +20,6 @@ import ( "github.com/dustin/go-humanize" "github.com/moistari/rls" "github.com/pkg/errors" - "github.com/rs/zerolog/log" ) type ReleaseRepo interface { @@ -274,8 +273,7 @@ func (r *Release) DownloadTorrentFile() error { req, err := http.NewRequest("GET", r.TorrentURL, nil) if err != nil { - log.Error().Stack().Err(err).Msg("error downloading file") - return err + return errors.Wrap(err, "error downloading file") } if r.RawCookie != "" { @@ -287,43 +285,37 @@ func (r *Release) DownloadTorrentFile() error { // Get the data resp, err := client.Do(req) if err != nil { - log.Error().Stack().Err(err).Msg("error downloading file") - return err + return errors.Wrap(err, "error downloading file") } defer resp.Body.Close() // retry logic if resp.StatusCode != http.StatusOK { - log.Error().Stack().Err(err).Msgf("error downloading file from: %v - bad status: %d", r.TorrentURL, resp.StatusCode) return fmt.Errorf("error downloading torrent (%v) file (%v) from '%v' - status code: %d", r.TorrentName, r.TorrentURL, r.Indexer, resp.StatusCode) } // Create tmp file tmpFile, err := os.CreateTemp("", "autobrr-") if err != nil { - log.Error().Stack().Err(err).Msg("error creating temp file") - return err + return errors.Wrap(err, "error creating tmp file") } defer tmpFile.Close() // Write the body to file _, err = io.Copy(tmpFile, resp.Body) if err != nil { - log.Error().Stack().Err(err).Msgf("error writing downloaded file: %v", tmpFile.Name()) - return err + return errors.Wrap(err, fmt.Sprintf("error writing downloaded file: %v", tmpFile.Name())) } meta, err := metainfo.LoadFromFile(tmpFile.Name()) if err != nil { - log.Error().Stack().Err(err).Msgf("metainfo could not load file contents: %v", tmpFile.Name()) - return err + return errors.Wrap(err, fmt.Sprintf("metainfo could not load file contents: %v", tmpFile.Name())) } torrentMetaInfo, err := meta.UnmarshalInfo() if err != nil { - log.Error().Stack().Err(err).Msgf("metainfo could not unmarshal info from torrent: %v", tmpFile.Name()) - return err + return errors.Wrap(err, fmt.Sprintf("metainfo could not unmarshal info from torrent: %v", tmpFile.Name())) } r.TorrentTmpFile = tmpFile.Name() @@ -332,7 +324,7 @@ func (r *Release) DownloadTorrentFile() error { // remove file if fail - log.Debug().Msgf("successfully downloaded file: %v", tmpFile.Name()) + //log.Debug().Msgf("successfully downloaded file: %v", tmpFile.Name()) return nil } diff --git a/internal/domain/release_test.go b/internal/domain/release_test.go index d191374..c34061d 100644 --- a/internal/domain/release_test.go +++ b/internal/domain/release_test.go @@ -438,7 +438,7 @@ func TestRelease_MapVars(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := tt.fields - _ = r.MapVars(tt.args.definition, tt.args.varMap) + _ = r.MapVars(&tt.args.definition, tt.args.varMap) assert.Equal(t, tt.want, r) }) diff --git a/internal/download_client/connection.go b/internal/download_client/connection.go index 4265f33..07bb265 100644 --- a/internal/download_client/connection.go +++ b/internal/download_client/connection.go @@ -1,18 +1,19 @@ package download_client import ( - "github.com/autobrr/autobrr/pkg/whisparr" - "github.com/pkg/errors" + "fmt" "time" + "github.com/pkg/errors" + "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/pkg/lidarr" "github.com/autobrr/autobrr/pkg/qbittorrent" "github.com/autobrr/autobrr/pkg/radarr" "github.com/autobrr/autobrr/pkg/sonarr" + "github.com/autobrr/autobrr/pkg/whisparr" delugeClient "github.com/gdm85/go-libdeluge" - "github.com/rs/zerolog/log" ) func (s *service) testConnection(client domain.DownloadClient) error { @@ -52,11 +53,10 @@ func (s *service) testQbittorrentConnection(client domain.DownloadClient) error qbt := qbittorrent.NewClient(qbtSettings) err := qbt.Login() if err != nil { - log.Error().Err(err).Msgf("error logging into client: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("error logging into client: %v", client.Host)) } - log.Debug().Msgf("test client connection for qBittorrent: success") + s.log.Debug().Msgf("test client connection for qBittorrent: success") return nil } @@ -87,8 +87,7 @@ func (s *service) testDelugeConnection(client domain.DownloadClient) error { // perform connection to Deluge server err := deluge.Connect() if err != nil { - log.Error().Err(err).Msgf("error logging into client: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("error logging into client: %v", client.Host)) } defer deluge.Close() @@ -96,11 +95,10 @@ func (s *service) testDelugeConnection(client domain.DownloadClient) error { // print daemon version ver, err := deluge.DaemonVersion() if err != nil { - log.Error().Err(err).Msgf("could not get daemon version: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("could not get daemon version: %v", client.Host)) } - log.Debug().Msgf("test client connection for Deluge: success - daemon version: %v", ver) + s.log.Debug().Msgf("test client connection for Deluge: success - daemon version: %v", ver) return nil } @@ -116,11 +114,10 @@ func (s *service) testRadarrConnection(client domain.DownloadClient) error { _, err := r.Test() if err != nil { - log.Error().Err(err).Msgf("radarr: connection test failed: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("radarr: connection test failed: %v", client.Host)) } - log.Debug().Msgf("test client connection for Radarr: success") + s.log.Debug().Msgf("test client connection for Radarr: success") return nil } @@ -136,11 +133,10 @@ func (s *service) testSonarrConnection(client domain.DownloadClient) error { _, err := r.Test() if err != nil { - log.Error().Err(err).Msgf("sonarr: connection test failed: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("sonarr: connection test failed: %v", client.Host)) } - log.Debug().Msgf("test client connection for Sonarr: success") + s.log.Debug().Msgf("test client connection for Sonarr: success") return nil } @@ -156,11 +152,10 @@ func (s *service) testLidarrConnection(client domain.DownloadClient) error { _, err := r.Test() if err != nil { - log.Error().Err(err).Msgf("lidarr: connection test failed: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("lidarr: connection test failed: %v", client.Host)) } - log.Debug().Msgf("test client connection for Lidarr: success") + s.log.Debug().Msgf("test client connection for Lidarr: success") return nil } @@ -176,11 +171,10 @@ func (s *service) testWhisparrConnection(client domain.DownloadClient) error { _, err := r.Test() if err != nil { - log.Error().Err(err).Msgf("whisparr: connection test failed: %v", client.Host) - return err + return errors.Wrap(err, fmt.Sprintf("whisparr: connection test failed: %v", client.Host)) } - log.Debug().Msgf("test client connection for whisparr: success") + s.log.Debug().Msgf("test client connection for whisparr: success") return nil } diff --git a/internal/download_client/service.go b/internal/download_client/service.go index 52e9073..ae85e01 100644 --- a/internal/download_client/service.go +++ b/internal/download_client/service.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" ) type Service interface { @@ -17,11 +18,15 @@ type Service interface { } type service struct { + log logger.Logger repo domain.DownloadClientRepo } -func NewService(repo domain.DownloadClientRepo) Service { - return &service{repo: repo} +func NewService(log logger.Logger, repo domain.DownloadClientRepo) Service { + return &service{ + log: log, + repo: repo, + } } func (s *service) List(ctx context.Context) ([]domain.DownloadClient, error) { @@ -69,5 +74,10 @@ func (s *service) Test(client domain.DownloadClient) error { } // test - return s.testConnection(client) + if err := s.testConnection(client); err != nil { + s.log.Err(err).Msg("client connection test error") + return err + } + + return nil } diff --git a/internal/events/subscribers.go b/internal/events/subscribers.go index aff85c3..2d8cd03 100644 --- a/internal/events/subscribers.go +++ b/internal/events/subscribers.go @@ -4,21 +4,23 @@ import ( "context" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/notification" "github.com/autobrr/autobrr/internal/release" "github.com/asaskevich/EventBus" - "github.com/rs/zerolog/log" ) type Subscriber struct { + log logger.Logger eventbus EventBus.Bus notificationSvc notification.Service releaseSvc release.Service } -func NewSubscribers(eventbus EventBus.Bus, notificationSvc notification.Service, releaseSvc release.Service) Subscriber { +func NewSubscribers(log logger.Logger, eventbus EventBus.Bus, notificationSvc notification.Service, releaseSvc release.Service) Subscriber { s := Subscriber{ + log: log, eventbus: eventbus, notificationSvc: notificationSvc, releaseSvc: releaseSvc, @@ -36,26 +38,26 @@ func (s Subscriber) Register() { } func (s Subscriber) releaseActionStatus(actionStatus *domain.ReleaseActionStatus) { - log.Trace().Msgf("events: 'release:store-action-status' '%+v'", actionStatus) + s.log.Trace().Msgf("events: 'release:store-action-status' '%+v'", actionStatus) err := s.releaseSvc.StoreReleaseActionStatus(context.Background(), actionStatus) if err != nil { - log.Error().Err(err).Msgf("events: 'release:store-action-status' error") + s.log.Error().Err(err).Msgf("events: 'release:store-action-status' error") } } func (s Subscriber) releasePushStatus(actionStatus *domain.ReleaseActionStatus) { - log.Trace().Msgf("events: 'release:push' '%+v'", actionStatus) + s.log.Trace().Msgf("events: 'release:push' '%+v'", actionStatus) if err := s.releaseSvc.StoreReleaseActionStatus(context.Background(), actionStatus); err != nil { - log.Error().Err(err).Msgf("events: 'release:push' error") + s.log.Error().Err(err).Msgf("events: 'release:push' error") } } func (s Subscriber) releasePush(event *domain.EventsReleasePushed) { - log.Trace().Msgf("events: 'events:release:push' '%+v'", event) + s.log.Trace().Msgf("events: 'events:release:push' '%+v'", event) if err := s.notificationSvc.SendEvent(*event); err != nil { - log.Error().Err(err).Msgf("events: 'events:release:push' error sending notification") + s.log.Error().Err(err).Msgf("events: 'events:release:push' error sending notification") } } diff --git a/internal/feed/service.go b/internal/feed/service.go index 6869173..e4a248f 100644 --- a/internal/feed/service.go +++ b/internal/feed/service.go @@ -6,11 +6,10 @@ import ( "fmt" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/release" "github.com/autobrr/autobrr/internal/scheduler" "github.com/autobrr/autobrr/pkg/torznab" - - "github.com/rs/zerolog/log" ) type Service interface { @@ -35,6 +34,7 @@ type feedInstance struct { } type service struct { + log logger.Logger jobs map[string]int repo domain.FeedRepo @@ -43,8 +43,9 @@ type service struct { scheduler scheduler.Service } -func NewService(repo domain.FeedRepo, cacheRepo domain.FeedCacheRepo, releaseSvc release.Service, scheduler scheduler.Service) Service { +func NewService(log logger.Logger, repo domain.FeedRepo, cacheRepo domain.FeedCacheRepo, releaseSvc release.Service, scheduler scheduler.Service) Service { return &service{ + log: log, jobs: map[string]int{}, repo: repo, cacheRepo: cacheRepo, @@ -83,12 +84,12 @@ func (s *service) ToggleEnabled(ctx context.Context, id int, enabled bool) error func (s *service) update(ctx context.Context, feed *domain.Feed) error { if err := s.repo.Update(ctx, feed); err != nil { - log.Error().Err(err).Msg("feed.Update: error updating feed") + s.log.Error().Err(err).Msg("feed.Update: error updating feed") return err } if err := s.restartJob(feed); err != nil { - log.Error().Err(err).Msg("feed.Update: error restarting feed") + s.log.Error().Err(err).Msg("feed.Update: error restarting feed") return err } @@ -98,54 +99,54 @@ func (s *service) update(ctx context.Context, feed *domain.Feed) error { func (s *service) delete(ctx context.Context, id int) error { f, err := s.repo.FindByID(ctx, id) if err != nil { - log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed") + s.log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed") return err } if err := s.stopTorznabJob(f.Indexer); err != nil { - log.Error().Err(err).Msg("feed.Delete: error stopping torznab job") + s.log.Error().Err(err).Msg("feed.Delete: error stopping torznab job") return err } if err := s.repo.Delete(ctx, id); err != nil { - log.Error().Err(err).Msg("feed.Delete: error deleting feed") + s.log.Error().Err(err).Msg("feed.Delete: error deleting feed") return err } - log.Debug().Msgf("feed.Delete: stopping and removing feed: %v", f.Name) + s.log.Debug().Msgf("feed.Delete: stopping and removing feed: %v", f.Name) return nil } func (s *service) toggleEnabled(ctx context.Context, id int, enabled bool) error { if err := s.repo.ToggleEnabled(ctx, id, enabled); err != nil { - log.Error().Err(err).Msg("feed.ToggleEnabled: error toggle enabled") + s.log.Error().Err(err).Msg("feed.ToggleEnabled: error toggle enabled") return err } f, err := s.repo.FindByID(ctx, id) if err != nil { - log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed") + s.log.Error().Err(err).Msg("feed.ToggleEnabled: error finding feed") return err } if !enabled { if err := s.stopTorznabJob(f.Indexer); err != nil { - log.Error().Err(err).Msg("feed.ToggleEnabled: error stopping torznab job") + s.log.Error().Err(err).Msg("feed.ToggleEnabled: error stopping torznab job") return err } - log.Debug().Msgf("feed.ToggleEnabled: stopping feed: %v", f.Name) + s.log.Debug().Msgf("feed.ToggleEnabled: stopping feed: %v", f.Name) return nil } if err := s.startJob(*f); err != nil { - log.Error().Err(err).Msg("feed.ToggleEnabled: error starting torznab job") + s.log.Error().Err(err).Msg("feed.ToggleEnabled: error starting torznab job") return err } - log.Debug().Msgf("feed.ToggleEnabled: started feed: %v", f.Name) + s.log.Debug().Msgf("feed.ToggleEnabled: started feed: %v", f.Name) return nil } @@ -154,13 +155,13 @@ func (s *service) Start() error { // get all torznab indexer definitions feeds, err := s.repo.Find(context.TODO()) if err != nil { - log.Error().Err(err).Msg("feed.Start: error getting feeds") + s.log.Error().Err(err).Msg("feed.Start: error getting feeds") return err } for _, i := range feeds { if err := s.startJob(i); err != nil { - log.Error().Err(err).Msg("feed.Start: failed to initialize torznab job") + s.log.Error().Err(err).Msg("feed.Start: failed to initialize torznab job") continue } } @@ -171,19 +172,19 @@ func (s *service) Start() error { func (s *service) restartJob(f *domain.Feed) error { // stop feed if err := s.stopTorznabJob(f.Indexer); err != nil { - log.Error().Err(err).Msg("feed.restartJob: error stopping torznab job") + s.log.Error().Err(err).Msg("feed.restartJob: error stopping torznab job") return err } - log.Debug().Msgf("feed.restartJob: stopping feed: %v", f.Name) + s.log.Debug().Msgf("feed.restartJob: stopping feed: %v", f.Name) if f.Enabled { if err := s.startJob(*f); err != nil { - log.Error().Err(err).Msg("feed.restartJob: error starting torznab job") + s.log.Error().Err(err).Msg("feed.restartJob: error starting torznab job") return err } - log.Debug().Msgf("feed.restartJob: restarted feed: %v", f.Name) + s.log.Debug().Msgf("feed.restartJob: restarted feed: %v", f.Name) } return nil @@ -215,7 +216,7 @@ func (s *service) startJob(f domain.Feed) error { switch fi.Implementation { case string(domain.FeedTypeTorznab): if err := s.addTorznabJob(fi); err != nil { - log.Error().Err(err).Msg("feed.startJob: failed to initialize feed") + s.log.Error().Err(err).Msg("feed.startJob: failed to initialize feed") return err } //case "rss": @@ -234,7 +235,7 @@ func (s *service) addTorznabJob(f feedInstance) error { } // setup logger - l := log.With().Str("feed_name", f.Name).Logger() + l := s.log.With().Str("feed_name", f.Name).Logger() // setup torznab Client c := torznab.NewClient(f.URL, f.ApiKey) @@ -260,7 +261,7 @@ func (s *service) addTorznabJob(f feedInstance) error { // add to job map s.jobs[f.IndexerIdentifier] = id - log.Debug().Msgf("feed.AddTorznabJob: %v", f.Name) + s.log.Debug().Msgf("feed.AddTorznabJob: %v", f.Name) return nil } @@ -271,7 +272,7 @@ func (s *service) stopTorznabJob(indexer string) error { return fmt.Errorf("feed.stopTorznabJob: stop job failed: %w", err) } - log.Debug().Msgf("feed.stopTorznabJob: %v", indexer) + s.log.Debug().Msgf("feed.stopTorznabJob: %v", indexer) return nil } diff --git a/internal/feed/torznab.go b/internal/feed/torznab.go index ac62e51..33810d9 100644 --- a/internal/feed/torznab.go +++ b/internal/feed/torznab.go @@ -5,11 +5,11 @@ import ( "sort" "time" + "github.com/rs/zerolog" + "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/internal/release" "github.com/autobrr/autobrr/pkg/torznab" - - "github.com/rs/zerolog" ) type TorznabJob struct { diff --git a/internal/filter/service.go b/internal/filter/service.go index af38a1c..ab2e23d 100644 --- a/internal/filter/service.go +++ b/internal/filter/service.go @@ -5,11 +5,11 @@ import ( "errors" "fmt" - "github.com/dustin/go-humanize" - "github.com/rs/zerolog/log" - "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/internal/indexer" + "github.com/autobrr/autobrr/internal/logger" + + "github.com/dustin/go-humanize" ) type Service interface { @@ -25,14 +25,16 @@ type Service interface { } type service struct { + log logger.Logger repo domain.FilterRepo actionRepo domain.ActionRepo indexerSvc indexer.Service apiService indexer.APIService } -func NewService(repo domain.FilterRepo, actionRepo domain.ActionRepo, apiService indexer.APIService, indexerSvc indexer.Service) Service { +func NewService(log logger.Logger, repo domain.FilterRepo, actionRepo domain.ActionRepo, apiService indexer.APIService, indexerSvc indexer.Service) Service { return &service{ + log: log, repo: repo, actionRepo: actionRepo, apiService: apiService, @@ -72,14 +74,14 @@ func (s *service) FindByID(ctx context.Context, filterID int) (*domain.Filter, e // find actions and attach actions, err := s.actionRepo.FindByFilterID(ctx, filter.ID) if err != nil { - log.Error().Msgf("could not find filter actions: %+v", &filter.ID) + s.log.Error().Msgf("could not find filter actions: %+v", &filter.ID) } filter.Actions = actions // find indexers and attach indexers, err := s.indexerSvc.FindByFilterID(ctx, filter.ID) if err != nil { - log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &filter.Name) + s.log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &filter.Name) return nil, err } filter.Indexers = indexers @@ -91,7 +93,7 @@ func (s *service) FindByIndexerIdentifier(indexer string) ([]domain.Filter, erro // get filters for indexer filters, err := s.repo.FindByIndexerIdentifier(indexer) if err != nil { - log.Error().Err(err).Msgf("could not find filters for indexer: %v", indexer) + s.log.Error().Err(err).Msgf("could not find filters for indexer: %v", indexer) return nil, err } @@ -104,7 +106,7 @@ func (s *service) Store(ctx context.Context, filter domain.Filter) (*domain.Filt // store f, err := s.repo.Store(ctx, filter) if err != nil { - log.Error().Err(err).Msgf("could not store filter: %v", filter) + s.log.Error().Err(err).Msgf("could not store filter: %v", filter) return nil, err } @@ -120,20 +122,20 @@ func (s *service) Update(ctx context.Context, filter domain.Filter) (*domain.Fil // update f, err := s.repo.Update(ctx, filter) if err != nil { - log.Error().Err(err).Msgf("could not update filter: %v", filter.Name) + s.log.Error().Err(err).Msgf("could not update filter: %v", filter.Name) return nil, err } // take care of connected indexers if err = s.repo.StoreIndexerConnections(ctx, f.ID, filter.Indexers); err != nil { - log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name) + s.log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name) return nil, err } // take care of filter actions actions, err := s.actionRepo.StoreFilterActions(ctx, filter.Actions, int64(filter.ID)) if err != nil { - log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name) + s.log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name) return nil, err } @@ -155,27 +157,27 @@ func (s *service) Duplicate(ctx context.Context, filterID int) (*domain.Filter, // find actions and attach filterActions, err := s.actionRepo.FindByFilterID(ctx, filterID) if err != nil { - log.Error().Msgf("could not find filter actions: %+v", &filterID) + s.log.Error().Msgf("could not find filter actions: %+v", &filterID) return nil, err } // find indexers and attach filterIndexers, err := s.indexerSvc.FindByFilterID(ctx, filterID) if err != nil { - log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &baseFilter.Name) + s.log.Error().Err(err).Msgf("could not find indexers for filter: %+v", &baseFilter.Name) return nil, err } // update filter, err := s.repo.Store(ctx, *baseFilter) if err != nil { - log.Error().Err(err).Msgf("could not update filter: %v", baseFilter.Name) + s.log.Error().Err(err).Msgf("could not update filter: %v", baseFilter.Name) return nil, err } // take care of connected indexers if err = s.repo.StoreIndexerConnections(ctx, filter.ID, filterIndexers); err != nil { - log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name) + s.log.Error().Err(err).Msgf("could not store filter indexer connections: %v", filter.Name) return nil, err } filter.Indexers = filterIndexers @@ -183,7 +185,7 @@ func (s *service) Duplicate(ctx context.Context, filterID int) (*domain.Filter, // take care of filter actions actions, err := s.actionRepo.StoreFilterActions(ctx, filterActions, int64(filter.ID)) if err != nil { - log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name) + s.log.Error().Err(err).Msgf("could not store filter actions: %v", filter.Name) return nil, err } @@ -194,11 +196,11 @@ func (s *service) Duplicate(ctx context.Context, filterID int) (*domain.Filter, func (s *service) ToggleEnabled(ctx context.Context, filterID int, enabled bool) error { if err := s.repo.ToggleEnabled(ctx, filterID, enabled); err != nil { - log.Error().Err(err).Msg("could not update filter enabled") + s.log.Error().Err(err).Msg("could not update filter enabled") return err } - log.Debug().Msgf("filter.toggle_enabled: update filter '%v' to '%v'", filterID, enabled) + s.log.Debug().Msgf("filter.toggle_enabled: update filter '%v' to '%v'", filterID, enabled) return nil } @@ -210,19 +212,19 @@ func (s *service) Delete(ctx context.Context, filterID int) error { // take care of filter actions if err := s.actionRepo.DeleteByFilterID(ctx, filterID); err != nil { - log.Error().Err(err).Msg("could not delete filter actions") + s.log.Error().Err(err).Msg("could not delete filter actions") return err } // take care of filter indexers if err := s.repo.DeleteIndexerConnections(ctx, filterID); err != nil { - log.Error().Err(err).Msg("could not delete filter indexers") + s.log.Error().Err(err).Msg("could not delete filter indexers") return err } // delete filter if err := s.repo.Delete(ctx, filterID); err != nil { - log.Error().Err(err).Msgf("could not delete filter: %v", filterID) + s.log.Error().Err(err).Msgf("could not delete filter: %v", filterID) return err } @@ -231,19 +233,19 @@ func (s *service) Delete(ctx context.Context, filterID int) error { func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, error) { - log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v %+v", f.Name, f) - log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v for release: %+v", f.Name, release) + s.log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v %+v", f.Name, f) + s.log.Trace().Msgf("filter.Service.CheckFilter: checking filter: %v for release: %+v", f.Name, release) rejections, matchedFilter := f.CheckFilter(release) if len(rejections) > 0 { - log.Trace().Msgf("filter.Service.CheckFilter: (%v) for release: %v rejections: (%v)", f.Name, release.TorrentName, release.RejectionsString()) + s.log.Trace().Msgf("filter.Service.CheckFilter: (%v) for release: %v rejections: (%v)", f.Name, release.TorrentName, release.RejectionsString()) return false, nil } if matchedFilter { // if matched, do additional size check if needed, attach actions and return the filter - log.Debug().Msgf("filter.Service.CheckFilter: found and matched filter: %+v", f.Name) + s.log.Debug().Msgf("filter.Service.CheckFilter: found and matched filter: %+v", f.Name) // Some indexers do not announce the size and if size (min,max) is set in a filter then it will need // additional size check. Some indexers have api implemented to fetch this data and for the others @@ -251,16 +253,16 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e // do additional size check against indexer api or download torrent for size check if release.AdditionalSizeCheckRequired { - log.Debug().Msgf("filter.Service.CheckFilter: (%v) additional size check required", f.Name) + s.log.Debug().Msgf("filter.Service.CheckFilter: (%v) additional size check required", f.Name) ok, err := s.AdditionalSizeCheck(f, release) if err != nil { - log.Error().Stack().Err(err).Msgf("filter.Service.CheckFilter: (%v) additional size check error", f.Name) + s.log.Error().Stack().Err(err).Msgf("filter.Service.CheckFilter: (%v) additional size check error", f.Name) return false, err } if !ok { - log.Trace().Msgf("filter.Service.CheckFilter: (%v) additional size check not matching what filter wanted", f.Name) + s.log.Trace().Msgf("filter.Service.CheckFilter: (%v) additional size check not matching what filter wanted", f.Name) return false, nil } } @@ -268,13 +270,13 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e // found matching filter, lets find the filter actions and attach actions, err := s.actionRepo.FindByFilterID(context.TODO(), f.ID) if err != nil { - log.Error().Err(err).Msgf("filter.Service.CheckFilter: error finding actions for filter: %+v", f.Name) + s.log.Error().Err(err).Msgf("filter.Service.CheckFilter: error finding actions for filter: %+v", f.Name) return false, err } // if no actions, continue to next filter if len(actions) == 0 { - log.Trace().Msgf("filter.Service.CheckFilter: no actions found for filter '%v', trying next one..", f.Name) + s.log.Trace().Msgf("filter.Service.CheckFilter: no actions found for filter '%v', trying next one..", f.Name) return false, err } release.Filter.Actions = actions @@ -293,30 +295,30 @@ func (s *service) CheckFilter(f domain.Filter, release *domain.Release) (bool, e func (s *service) AdditionalSizeCheck(f domain.Filter, release *domain.Release) (bool, error) { // do additional size check against indexer api or torrent for size - log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) additional size check required", f.Name) + s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) additional size check required", f.Name) switch release.Indexer { case "ptp", "btn", "ggn", "redacted", "mock": if release.Size == 0 { - log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to check via api", f.Name) + s.log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to check via api", f.Name) torrentInfo, err := s.apiService.GetTorrentByID(release.Indexer, release.TorrentID) if err != nil || torrentInfo == nil { - log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not get torrent info from api: '%v' from: %v", f.Name, release.TorrentID, release.Indexer) + s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not get torrent info from api: '%v' from: %v", f.Name, release.TorrentID, release.Indexer) return false, err } - log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) got torrent info from api: %+v", f.Name, torrentInfo) + s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) got torrent info from api: %+v", f.Name, torrentInfo) release.Size = torrentInfo.ReleaseSizeBytes() } default: - log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to download torrent metafile", f.Name) + s.log.Trace().Msgf("filter.Service.AdditionalSizeCheck: (%v) preparing to download torrent metafile", f.Name) // if indexer doesn't have api, download torrent and add to tmpPath err := release.DownloadTorrentFile() if err != nil { - log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not download torrent file with id: '%v' from: %v", f.Name, release.TorrentID, release.Indexer) + s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) could not download torrent file with id: '%v' from: %v", f.Name, release.TorrentID, release.Indexer) return false, err } } @@ -324,12 +326,12 @@ func (s *service) AdditionalSizeCheck(f domain.Filter, release *domain.Release) // compare size against filter match, err := checkSizeFilter(f.MinSize, f.MaxSize, release.Size) if err != nil { - log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) error checking extra size filter", f.Name) + s.log.Error().Stack().Err(err).Msgf("filter.Service.AdditionalSizeCheck: (%v) error checking extra size filter", f.Name) return false, err } //no match, lets continue to next filter if !match { - log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) filter did not match after additional size check, trying next", f.Name) + s.log.Debug().Msgf("filter.Service.AdditionalSizeCheck: (%v) filter did not match after additional size check, trying next", f.Name) return false, nil } diff --git a/internal/http/auth.go b/internal/http/auth.go index d30851e..a725aa0 100644 --- a/internal/http/auth.go +++ b/internal/http/auth.go @@ -19,13 +19,13 @@ type authService interface { type authHandler struct { encoder encoder - config domain.Config + config *domain.Config service authService cookieStore *sessions.CookieStore } -func newAuthHandler(encoder encoder, config domain.Config, cookieStore *sessions.CookieStore, service authService) *authHandler { +func newAuthHandler(encoder encoder, config *domain.Config, cookieStore *sessions.CookieStore, service authService) *authHandler { return &authHandler{ encoder: encoder, config: config, diff --git a/internal/http/config.go b/internal/http/config.go index 2a2e38a..381cf13 100644 --- a/internal/http/config.go +++ b/internal/http/config.go @@ -3,8 +3,6 @@ package http import ( "net/http" - "github.com/autobrr/autobrr/internal/config" - "github.com/go-chi/chi" ) @@ -39,14 +37,12 @@ func (h configHandler) Routes(r chi.Router) { func (h configHandler) getConfig(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - c := config.Config - conf := configJson{ - Host: c.Host, - Port: c.Port, - LogLevel: c.LogLevel, - LogPath: c.LogPath, - BaseURL: c.BaseURL, + Host: h.server.config.Host, + Port: h.server.config.Port, + LogLevel: h.server.config.LogLevel, + LogPath: h.server.config.LogPath, + BaseURL: h.server.config.BaseURL, Version: h.server.version, Commit: h.server.commit, Date: h.server.date, diff --git a/internal/http/server.go b/internal/http/server.go index c4869da..faa218d 100644 --- a/internal/http/server.go +++ b/internal/http/server.go @@ -20,7 +20,7 @@ type Server struct { sse *sse.Server db *database.DB - config domain.Config + config *domain.Config cookieStore *sessions.CookieStore version string @@ -38,7 +38,7 @@ type Server struct { releaseService releaseService } -func NewServer(config domain.Config, sse *sse.Server, db *database.DB, version string, commit string, date string, actionService actionService, authService authService, downloadClientSvc downloadClientService, filterSvc filterService, feedSvc feedService, indexerSvc indexerService, ircSvc ircService, notificationSvc notificationService, releaseSvc releaseService) Server { +func NewServer(config *domain.Config, sse *sse.Server, db *database.DB, version string, commit string, date string, actionService actionService, authService authService, downloadClientSvc downloadClientService, filterSvc filterService, feedSvc feedService, indexerSvc indexerService, ircSvc ircService, notificationSvc notificationService, releaseSvc releaseService) Server { return Server{ config: config, sse: sse, diff --git a/internal/indexer/api.go b/internal/indexer/api.go index 44b8c35..1a09aa4 100644 --- a/internal/indexer/api.go +++ b/internal/indexer/api.go @@ -4,13 +4,12 @@ import ( "fmt" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/mock" "github.com/autobrr/autobrr/pkg/btn" "github.com/autobrr/autobrr/pkg/ggn" "github.com/autobrr/autobrr/pkg/ptp" "github.com/autobrr/autobrr/pkg/red" - - "github.com/rs/zerolog/log" ) type APIService interface { @@ -26,11 +25,13 @@ type apiClient interface { } type apiService struct { + log logger.Logger apiClients map[string]apiClient } -func NewAPIService() APIService { +func NewAPIService(log logger.Logger) APIService { return &apiService{ + log: log, apiClients: make(map[string]apiClient), } } @@ -41,15 +42,15 @@ func (s *apiService) GetTorrentByID(indexer string, torrentID string) (*domain.T return nil, nil } - log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' trying to fetch torrent from api", indexer) + s.log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' trying to fetch torrent from api", indexer) t, err := v.GetTorrentByID(torrentID) if err != nil { - log.Error().Stack().Err(err).Msgf("could not get torrent: '%v' from: %v", torrentID, indexer) + s.log.Error().Stack().Err(err).Msgf("could not get torrent: '%v' from: %v", torrentID, indexer) return nil, err } - log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' successfully fetched torrent from api: %+v", indexer, t) + s.log.Trace().Str("service", "api").Str("method", "GetTorrentByID").Msgf("'%v' successfully fetched torrent from api: %+v", indexer, t) return t, nil } @@ -76,7 +77,7 @@ func (s *apiService) AddClient(indexer string, settings map[string]string) error return fmt.Errorf("api.Service.AddClient: validation falied: settings can't be empty") } - log.Trace().Msgf("api.Service.AddClient: init api client for '%v'", indexer) + s.log.Trace().Msgf("api.Service.AddClient: init api client for '%v'", indexer) // init client switch indexer { diff --git a/internal/indexer/service.go b/internal/indexer/service.go index e62de4a..17955ae 100644 --- a/internal/indexer/service.go +++ b/internal/indexer/service.go @@ -10,10 +10,10 @@ import ( "strings" "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/scheduler" "github.com/gosimple/slug" - "github.com/rs/zerolog/log" "gopkg.in/yaml.v2" ) @@ -32,7 +32,8 @@ type Service interface { } type service struct { - config domain.Config + log logger.Logger + config *domain.Config repo domain.IndexerRepo apiService APIService scheduler scheduler.Service @@ -48,8 +49,9 @@ type service struct { torznabIndexers map[string]*domain.IndexerDefinition } -func NewService(config domain.Config, repo domain.IndexerRepo, apiService APIService, scheduler scheduler.Service) Service { +func NewService(log logger.Logger, config *domain.Config, repo domain.IndexerRepo, apiService APIService, scheduler scheduler.Service) Service { return &service{ + log: log, config: config, repo: repo, apiService: apiService, @@ -73,14 +75,14 @@ func (s *service) Store(ctx context.Context, indexer domain.Indexer) (*domain.In i, err := s.repo.Store(ctx, indexer) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to store indexer: %v", indexer.Name) + s.log.Error().Stack().Err(err).Msgf("failed to store indexer: %v", indexer.Name) return nil, err } // add to indexerInstances err = s.addIndexer(*i) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name) + s.log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name) return nil, err } @@ -96,7 +98,7 @@ func (s *service) Update(ctx context.Context, indexer domain.Indexer) (*domain.I // add to indexerInstances err = s.addIndexer(*i) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name) + s.log.Error().Stack().Err(err).Msgf("failed to add indexer: %v", indexer.Name) return nil, err } @@ -238,7 +240,7 @@ func (s *service) Start() error { // check if it has api and add to api service if indexer.Enabled && indexer.HasApi() { if err := s.apiService.AddClient(indexer.Identifier, indexer.SettingsMap); err != nil { - log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier) + s.log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier) } } } @@ -249,7 +251,7 @@ func (s *service) Start() error { } } - log.Info().Msgf("Loaded %d indexers", len(indexerDefinitions)) + s.log.Info().Msgf("Loaded %d indexers", len(indexerDefinitions)) return nil } @@ -290,7 +292,7 @@ func (s *service) addIndexer(indexer domain.Indexer) error { // check if it has api and add to api service if indexerDefinition.Enabled && indexerDefinition.HasApi() { if err := s.apiService.AddClient(indexerDefinition.Identifier, indexerDefinition.SettingsMap); err != nil { - log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier) + s.log.Error().Stack().Err(err).Msgf("indexer.start: could not init api client for: '%v'", indexer.Identifier) } } } @@ -344,11 +346,11 @@ func (s *service) LoadIndexerDefinitions() error { entries, err := fs.ReadDir(Definitions, "definitions") if err != nil { - log.Fatal().Stack().Msgf("failed reading directory: %s", err) + s.log.Fatal().Stack().Msgf("failed reading directory: %s", err) } if len(entries) == 0 { - log.Fatal().Stack().Msgf("failed reading directory: %s", err) + s.log.Fatal().Stack().Msgf("failed reading directory: %s", err) return err } @@ -360,19 +362,19 @@ func (s *service) LoadIndexerDefinitions() error { file := "definitions/" + f.Name() - log.Trace().Msgf("parsing: %v", file) + s.log.Trace().Msgf("parsing: %v", file) var d *domain.IndexerDefinition data, err := fs.ReadFile(Definitions, file) if err != nil { - log.Error().Stack().Err(err).Msgf("failed reading file: %v", file) + s.log.Error().Stack().Err(err).Msgf("failed reading file: %v", file) return err } err = yaml.Unmarshal(data, &d) if err != nil { - log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file) + s.log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file) return err } @@ -383,7 +385,7 @@ func (s *service) LoadIndexerDefinitions() error { s.indexerDefinitions[d.Identifier] = d } - log.Debug().Msgf("Loaded %d indexer definitions", len(s.indexerDefinitions)) + s.log.Debug().Msgf("Loaded %d indexer definitions", len(s.indexerDefinitions)) return nil } @@ -399,11 +401,11 @@ func (s *service) LoadCustomIndexerDefinitions() error { //entries, err := fs.ReadDir(Definitions, "definitions") entries, err := outputDirRead.ReadDir(0) if err != nil { - log.Fatal().Stack().Msgf("failed reading directory: %s", err) + s.log.Fatal().Stack().Msgf("failed reading directory: %s", err) } if len(entries) == 0 { - log.Fatal().Stack().Msgf("failed reading directory: %s", err) + s.log.Fatal().Stack().Msgf("failed reading directory: %s", err) return err } @@ -417,20 +419,20 @@ func (s *service) LoadCustomIndexerDefinitions() error { file := filepath.Join(s.config.CustomDefinitions, f.Name()) - log.Trace().Msgf("parsing custom: %v", file) + s.log.Trace().Msgf("parsing custom: %v", file) var d *domain.IndexerDefinition //data, err := fs.ReadFile(Definitions, filePath) data, err := os.ReadFile(file) if err != nil { - log.Error().Stack().Err(err).Msgf("failed reading file: %v", file) + s.log.Error().Stack().Err(err).Msgf("failed reading file: %v", file) return err } err = yaml.Unmarshal(data, &d) if err != nil { - log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file) + s.log.Error().Stack().Err(err).Msgf("failed unmarshal file: %v", file) return err } @@ -443,7 +445,7 @@ func (s *service) LoadCustomIndexerDefinitions() error { customCount++ } - log.Debug().Msgf("Loaded %d custom indexer definitions", customCount) + s.log.Debug().Msgf("Loaded %d custom indexer definitions", customCount) return nil } diff --git a/internal/irc/handler.go b/internal/irc/handler.go index 8ffa598..442b3e8 100644 --- a/internal/irc/handler.go +++ b/internal/irc/handler.go @@ -13,9 +13,10 @@ import ( "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/release" + "github.com/dcarbone/zadapters/zstdlog" "github.com/ergochat/irc-go/ircevent" "github.com/ergochat/irc-go/ircmsg" - "github.com/rs/zerolog/log" + "github.com/rs/zerolog" ) var ( @@ -55,6 +56,7 @@ func (h *channelHealth) resetMonitoring() { } type Handler struct { + log zerolog.Logger network *domain.IrcNetwork releaseSvc release.Service announceProcessors map[string]announce.Processor @@ -73,8 +75,9 @@ type Handler struct { channelHealth map[string]*channelHealth } -func NewHandler(network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service) *Handler { +func NewHandler(log logger.Logger, network domain.IrcNetwork, definitions []*domain.IndexerDefinition, releaseSvc release.Service) *Handler { h := &Handler{ + log: log.With().Time("time", time.Now()).Str("network", network.Server).Logger(), client: nil, network: &network, releaseSvc: releaseSvc, @@ -106,7 +109,7 @@ func (h *Handler) InitIndexers(definitions []*domain.IndexerDefinition) { // some channels are defined in mixed case channel = strings.ToLower(channel) - h.announceProcessors[channel] = announce.NewAnnounceProcessor(h.releaseSvc, definition) + h.announceProcessors[channel] = announce.NewAnnounceProcessor(h.log, h.releaseSvc, definition) h.channelHealth[channel] = &channelHealth{ name: channel, @@ -134,6 +137,8 @@ func (h *Handler) removeIndexer() { func (h *Handler) Run() error { addr := fmt.Sprintf("%v:%d", h.network.Server, h.network.Port) + subLogger := zstdlog.NewStdLoggerWithLevel(h.log.With().Logger(), zerolog.TraceLevel) + h.client = &ircevent.Connection{ Nick: h.network.NickServ.Account, User: h.network.NickServ.Account, @@ -141,12 +146,12 @@ func (h *Handler) Run() error { Password: h.network.Pass, Server: addr, KeepAlive: 4 * time.Minute, - Timeout: 1 * time.Minute, + Timeout: 2 * time.Minute, ReconnectFreq: 15 * time.Second, Version: "autobrr", QuitMessage: "bye from autobrr", Debug: true, - Log: logger.StdLeveledLogger, + Log: subLogger, } if h.network.TLS { @@ -162,7 +167,7 @@ func (h *Handler) Run() error { h.client.AddCallback("PRIVMSG", h.onMessage) if err := h.client.Connect(); err != nil { - log.Error().Stack().Err(err).Msgf("%v: connect error", h.network.Server) + h.log.Error().Stack().Err(err).Msgf("%v: connect error", h.network.Server) // reset connection status on handler and channels h.resetConnectionStatus() @@ -233,12 +238,12 @@ func (h *Handler) AddChannelHealth(channel string) { } func (h *Handler) Stop() { - log.Debug().Msgf("%v: Disconnecting...", h.network.Server) + h.log.Debug().Msgf("%v: Disconnecting...", h.network.Server) h.client.Quit() } func (h *Handler) Restart() error { - log.Debug().Msgf("%v: Restarting network...", h.network.Server) + h.log.Debug().Msgf("%v: Restarting network...", h.network.Server) h.client.Quit() @@ -255,7 +260,7 @@ func (h *Handler) onConnect(m ircmsg.Message) { if h.network.NickServ.Password != "" { err := h.HandleNickServIdentify(h.network.NickServ.Password) if err != nil { - log.Error().Stack().Err(err).Msgf("error nickserv: %v", h.network.Name) + h.log.Error().Stack().Err(err).Msgf("error nickserv: %v", h.network.Name) return } identified = true @@ -266,7 +271,7 @@ func (h *Handler) onConnect(m ircmsg.Message) { if h.network.InviteCommand != "" { err := h.handleConnectCommands(h.network.InviteCommand) if err != nil { - log.Error().Stack().Err(err).Msgf("error sending connect command %v to network: %v", h.network.InviteCommand, h.network.Name) + h.log.Error().Stack().Err(err).Msgf("error sending connect command %v to network: %v", h.network.InviteCommand, h.network.Name) return } @@ -277,7 +282,7 @@ func (h *Handler) onConnect(m ircmsg.Message) { for _, channel := range h.network.Channels { err := h.HandleJoinChannel(channel.Name, channel.Password) if err != nil { - log.Error().Stack().Err(err).Msgf("error joining channels %v", err) + h.log.Error().Stack().Err(err).Msgf("error joining channels %v", err) return } } @@ -307,11 +312,11 @@ func (h *Handler) onMessage(msg ircmsg.Message) { } // clean message - cleanedMsg := cleanMessage(message) - log.Debug().Msgf("%v: %v %v: %v", h.network.Server, channel, announcer, cleanedMsg) + cleanedMsg := h.cleanMessage(message) + h.log.Debug().Msgf("%v: %v %v: %v", h.network.Server, channel, announcer, cleanedMsg) if err := h.sendToAnnounceProcessor(channel, cleanedMsg); err != nil { - log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg) + h.log.Error().Stack().Err(err).Msgf("could not queue line: %v", cleanedMsg) return } @@ -330,7 +335,7 @@ func (h *Handler) sendToAnnounceProcessor(channel string, msg string) error { // if it exists, add msg err := queue.AddLineToQueue(channel, msg) if err != nil { - log.Error().Stack().Err(err).Msgf("could not queue line: %v", msg) + h.log.Error().Stack().Err(err).Msgf("could not queue line: %v", msg) return err } @@ -355,11 +360,11 @@ func (h *Handler) HandleJoinChannel(channel string, password string) error { m.Params = []string{channel, password} } - log.Debug().Msgf("%v: sending JOIN command %v", h.network.Server, strings.Join(m.Params, " ")) + h.log.Debug().Msgf("%v: sending JOIN command %v", h.network.Server, strings.Join(m.Params, " ")) err := h.client.SendIRCMessage(m) if err != nil { - log.Error().Stack().Err(err).Msgf("error handling join: %v", channel) + h.log.Error().Stack().Err(err).Msgf("error handling join: %v", channel) return err } @@ -368,17 +373,17 @@ func (h *Handler) HandleJoinChannel(channel string, password string) error { func (h *Handler) handlePart(msg ircmsg.Message) { if !h.isOurNick(msg.Nick()) { - log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg) + h.log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg) return } channel := msg.Params[0] - log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel) + h.log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel) err := h.client.Part(channel) if err != nil { - log.Error().Err(err).Msgf("error handling part: %v", channel) + h.log.Error().Err(err).Msgf("error handling part: %v", channel) return } @@ -392,17 +397,17 @@ func (h *Handler) handlePart(msg ircmsg.Message) { // TODO remove announceProcessor - log.Info().Msgf("%v: Left channel '%v'", h.network.Server, channel) + h.log.Info().Msgf("%v: Left channel '%v'", h.network.Server, channel) return } func (h *Handler) HandlePartChannel(channel string) error { - log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel) + h.log.Debug().Msgf("%v: PART channel %v", h.network.Server, channel) err := h.client.Part(channel) if err != nil { - log.Error().Err(err).Msgf("error handling part: %v", channel) + h.log.Error().Err(err).Msgf("error handling part: %v", channel) return err } @@ -416,21 +421,21 @@ func (h *Handler) HandlePartChannel(channel string) error { // TODO remove announceProcessor - log.Info().Msgf("Left channel '%v' on network '%h'", channel, h.network.Server) + h.log.Info().Msgf("Left channel '%v' on network '%h'", channel, h.network.Server) return nil } func (h *Handler) handleJoined(msg ircmsg.Message) { if !h.isOurNick(msg.Params[0]) { - log.Debug().Msgf("%v: OTHER USER JOINED: %+v", h.network.Server, msg) + h.log.Debug().Msgf("%v: OTHER USER JOINED: %+v", h.network.Server, msg) return } // get channel channel := msg.Params[1] - log.Debug().Msgf("%v: JOINED: %v", h.network.Server, msg.Params[1]) + h.log.Debug().Msgf("%v: JOINED: %v", h.network.Server, msg.Params[1]) // set monitoring on current channelHealth, or add new v, ok := h.channelHealth[strings.ToLower(channel)] @@ -442,7 +447,7 @@ func (h *Handler) handleJoined(msg ircmsg.Message) { valid := h.isValidChannel(channel) if valid { - log.Info().Msgf("%v: Monitoring channel %v", h.network.Server, msg.Params[1]) + h.log.Info().Msgf("%v: Monitoring channel %v", h.network.Server, msg.Params[1]) return } } @@ -459,11 +464,11 @@ func (h *Handler) handleConnectCommands(msg string) error { Params: strings.Split(cmd, " "), } - log.Debug().Msgf("%v: sending connect command", h.network.Server) + h.log.Debug().Msgf("%v: sending connect command", h.network.Server) err := h.client.SendIRCMessage(m) if err != nil { - log.Error().Err(err).Msgf("error handling invite: %v", m) + h.log.Error().Err(err).Msgf("error handling invite: %v", m) return err } } @@ -479,11 +484,11 @@ func (h *Handler) handleInvite(msg ircmsg.Message) { // get channel channel := msg.Params[1] - log.Debug().Msgf("%v: INVITE from %v, joining %v", h.network.Server, msg.Nick(), channel) + h.log.Debug().Msgf("%v: INVITE from %v, joining %v", h.network.Server, msg.Nick(), channel) err := h.client.Join(channel) if err != nil { - log.Error().Stack().Err(err).Msgf("error handling join: %v", channel) + h.log.Error().Stack().Err(err).Msgf("error handling join: %v", channel) return } @@ -496,11 +501,11 @@ func (h *Handler) HandleNickServIdentify(password string) error { Params: []string{"NickServ", "IDENTIFY", password}, } - log.Debug().Msgf("%v: NickServ: %v", h.network.Server, m) + h.log.Debug().Msgf("%v: NickServ: %v", h.network.Server, m) err := h.client.SendIRCMessage(m) if err != nil { - log.Error().Stack().Err(err).Msgf("error identifying with nickserv: %v", m) + h.log.Error().Stack().Err(err).Msgf("error identifying with nickserv: %v", m) return err } @@ -508,7 +513,7 @@ func (h *Handler) HandleNickServIdentify(password string) error { } func (h *Handler) HandleNickChange(nick string) error { - log.Debug().Msgf("%v: Nick change: %v", h.network.Server, nick) + h.log.Debug().Msgf("%v: Nick change: %v", h.network.Server, nick) h.client.SetNick(nick) @@ -516,24 +521,24 @@ func (h *Handler) HandleNickChange(nick string) error { } func (h *Handler) handleMode(msg ircmsg.Message) { - log.Debug().Msgf("%v: MODE: %+v", h.network.Server, msg) + h.log.Debug().Msgf("%v: MODE: %+v", h.network.Server, msg) if !h.isOurNick(msg.Params[0]) { - log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg) + h.log.Debug().Msgf("%v: MODE OTHER USER: %+v", h.network.Server, msg) return } time.Sleep(5 * time.Second) if h.network.NickServ.Password != "" && !strings.Contains(msg.Params[0], h.client.Nick) || !strings.Contains(msg.Params[1], "+r") { - log.Trace().Msgf("%v: MODE: Not correct permission yet: %v", h.network.Server, msg.Params) + h.log.Trace().Msgf("%v: MODE: Not correct permission yet: %v", h.network.Server, msg.Params) return } for _, ch := range h.network.Channels { err := h.HandleJoinChannel(ch.Name, ch.Password) if err != nil { - log.Error().Err(err).Msgf("error joining channel: %v", ch.Name) + h.log.Error().Err(err).Msgf("error joining channel: %v", ch.Name) continue } @@ -572,12 +577,12 @@ func (h *Handler) GetLastPing() time.Time { } // irc line can contain lots of extra stuff like color so lets clean that -func cleanMessage(message string) string { +func (h *Handler) cleanMessage(message string) string { var regexMessageClean = `\x0f|\x1f|\x02|\x03(?:[\d]{1,2}(?:,[\d]{1,2})?)?` rxp, err := regexp.Compile(regexMessageClean) if err != nil { - log.Error().Err(err).Msgf("error compiling regex: %v", regexMessageClean) + h.log.Error().Err(err).Msgf("error compiling regex: %v", regexMessageClean) return "" } diff --git a/internal/irc/service.go b/internal/irc/service.go index 87dd320..f63e2e1 100644 --- a/internal/irc/service.go +++ b/internal/irc/service.go @@ -8,10 +8,10 @@ import ( "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/internal/indexer" + "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/release" "github.com/pkg/errors" - "github.com/rs/zerolog/log" ) type Service interface { @@ -28,6 +28,7 @@ type Service interface { } type service struct { + log logger.Logger repo domain.IrcRepo releaseService release.Service indexerService indexer.Service @@ -38,8 +39,9 @@ type service struct { lock sync.Mutex } -func NewService(repo domain.IrcRepo, releaseSvc release.Service, indexerSvc indexer.Service) Service { +func NewService(log logger.Logger, repo domain.IrcRepo, releaseSvc release.Service, indexerSvc indexer.Service) Service { return &service{ + log: log, repo: repo, releaseService: releaseSvc, indexerService: indexerSvc, @@ -55,7 +57,7 @@ type handlerKey struct { func (s *service) StartHandlers() { networks, err := s.repo.FindActiveNetworks(context.Background()) if err != nil { - log.Error().Msgf("failed to list networks: %v", err) + s.log.Error().Msgf("failed to list networks: %v", err) } for _, network := range networks { @@ -69,7 +71,7 @@ func (s *service) StartHandlers() { s.lock.Lock() channels, err := s.repo.ListChannels(network.ID) if err != nil { - log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server) + s.log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server) } network.Channels = channels @@ -77,20 +79,20 @@ func (s *service) StartHandlers() { definitions := s.indexerService.GetIndexersByIRCNetwork(network.Server) // init new irc handler - handler := NewHandler(network, definitions, s.releaseService) + handler := NewHandler(s.log, network, definitions, s.releaseService) // use network.Server + nick to use multiple indexers with different nick per network // this allows for multiple handlers to one network s.handlers[handlerKey{network.Server, network.NickServ.Account}] = handler s.lock.Unlock() - log.Debug().Msgf("starting network: %+v", network.Name) + s.log.Debug().Msgf("starting network: %+v", network.Name) s.stopWG.Add(1) go func() { if err := handler.Run(); err != nil { - log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name) + s.log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name) } }() @@ -100,22 +102,22 @@ func (s *service) StartHandlers() { func (s *service) StopHandlers() { for _, handler := range s.handlers { - log.Info().Msgf("stopping network: %+v", handler.network.Name) + s.log.Info().Msgf("stopping network: %+v", handler.network.Name) handler.Stop() } - log.Info().Msg("stopped all irc handlers") + s.log.Info().Msg("stopped all irc handlers") } func (s *service) startNetwork(network domain.IrcNetwork) error { // look if we have the network in handlers already, if so start it if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found { - log.Debug().Msgf("starting network: %+v", network.Name) + s.log.Debug().Msgf("starting network: %+v", network.Name) if !existingHandler.client.Connected() { go func() { if err := existingHandler.Run(); err != nil { - log.Error().Err(err).Msgf("failed to start existingHandler for network %q", existingHandler.network.Name) + s.log.Error().Err(err).Msgf("failed to start existingHandler for network %q", existingHandler.network.Name) } }() } @@ -125,7 +127,7 @@ func (s *service) startNetwork(network domain.IrcNetwork) error { s.lock.Lock() channels, err := s.repo.ListChannels(network.ID) if err != nil { - log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server) + s.log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server) } network.Channels = channels @@ -133,18 +135,18 @@ func (s *service) startNetwork(network domain.IrcNetwork) error { definitions := s.indexerService.GetIndexersByIRCNetwork(network.Server) // init new irc handler - handler := NewHandler(network, definitions, s.releaseService) + handler := NewHandler(s.log, network, definitions, s.releaseService) s.handlers[handlerKey{network.Server, network.NickServ.Account}] = handler s.lock.Unlock() - log.Debug().Msgf("starting network: %+v", network.Name) + s.log.Debug().Msgf("starting network: %+v", network.Name) s.stopWG.Add(1) go func() { if err := handler.Run(); err != nil { - log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name) + s.log.Error().Err(err).Msgf("failed to start handler for network %q", network.Name) } }() @@ -157,7 +159,7 @@ func (s *service) startNetwork(network domain.IrcNetwork) error { func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error { // look if we have the network in handlers, if so restart it if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found { - log.Debug().Msgf("irc: decide if irc network handler needs restart or updating: %+v", network.Server) + s.log.Debug().Msgf("irc: decide if irc network handler needs restart or updating: %+v", network.Server) // if server, tls, invite command, port : changed - restart // if nickserv account, nickserv password : changed - stay connected, and change those @@ -176,7 +178,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error restartNeeded = true } if restartNeeded { - log.Info().Msgf("irc: restarting network: %+v", network.Server) + s.log.Info().Msgf("irc: restarting network: %+v", network.Server) // we need to reinitialize with new network config existingHandler.UpdateNetwork(network) @@ -185,7 +187,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error go func() { if err := existingHandler.Restart(); err != nil { - log.Error().Stack().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name) + s.log.Error().Stack().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name) } }() @@ -194,18 +196,18 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error } if handler.NickServ.Account != network.NickServ.Account { - log.Debug().Msg("changing nick") + s.log.Debug().Msg("changing nick") err := existingHandler.HandleNickChange(network.NickServ.Account) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to change nick %q", network.NickServ.Account) + s.log.Error().Stack().Err(err).Msgf("failed to change nick %q", network.NickServ.Account) } } else if handler.NickServ.Password != network.NickServ.Password { - log.Debug().Msg("nickserv: changing password") + s.log.Debug().Msg("nickserv: changing password") err := existingHandler.HandleNickServIdentify(network.NickServ.Password) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to identify with nickserv %q", network.NickServ.Account) + s.log.Error().Stack().Err(err).Msgf("failed to identify with nickserv %q", network.NickServ.Account) } } @@ -249,19 +251,19 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error // leave channels for _, leaveChannel := range channelsToLeave { - log.Debug().Msgf("%v: part channel %v", network.Server, leaveChannel) + s.log.Debug().Msgf("%v: part channel %v", network.Server, leaveChannel) err := existingHandler.HandlePartChannel(leaveChannel) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to leave channel: %q", leaveChannel) + s.log.Error().Stack().Err(err).Msgf("failed to leave channel: %q", leaveChannel) } } // join channels for _, joinChannel := range channelsToJoin { - log.Debug().Msgf("%v: join new channel %v", network.Server, joinChannel) + s.log.Debug().Msgf("%v: join new channel %v", network.Server, joinChannel) err := existingHandler.HandleJoinChannel(joinChannel.Name, joinChannel.Password) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to join channel: %q", joinChannel.Name) + s.log.Error().Stack().Err(err).Msgf("failed to join channel: %q", joinChannel.Name) } } @@ -277,7 +279,7 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error } else { err := s.startNetwork(*network) if err != nil { - log.Error().Stack().Err(err).Msgf("failed to start network: %q", network.Name) + s.log.Error().Stack().Err(err).Msgf("failed to start network: %q", network.Name) } } @@ -287,12 +289,12 @@ func (s *service) checkIfNetworkRestartNeeded(network *domain.IrcNetwork) error func (s *service) restartNetwork(network domain.IrcNetwork) error { // look if we have the network in handlers, if so restart it if existingHandler, found := s.handlers[handlerKey{network.Server, network.NickServ.Account}]; found { - log.Info().Msgf("restarting network: %v", network.Name) + s.log.Info().Msgf("restarting network: %v", network.Name) if existingHandler.client.Connected() { go func() { if err := existingHandler.Restart(); err != nil { - log.Error().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name) + s.log.Error().Err(err).Msgf("failed to restart network %q", existingHandler.network.Name) } }() } @@ -306,7 +308,7 @@ func (s *service) restartNetwork(network domain.IrcNetwork) error { func (s *service) StopNetwork(key handlerKey) error { if handler, found := s.handlers[key]; found { handler.Stop() - log.Debug().Msgf("stopped network: %+v", key.server) + s.log.Debug().Msgf("stopped network: %+v", key.server) } return nil @@ -318,7 +320,7 @@ func (s *service) StopAndRemoveNetwork(key handlerKey) error { // remove from handlers delete(s.handlers, key) - log.Debug().Msgf("stopped network: %+v", key) + s.log.Debug().Msgf("stopped network: %+v", key) } return nil @@ -327,7 +329,7 @@ func (s *service) StopAndRemoveNetwork(key handlerKey) error { func (s *service) StopNetworkIfRunning(key handlerKey) error { if handler, found := s.handlers[key]; found { handler.Stop() - log.Debug().Msgf("stopped network: %+v", key.server) + s.log.Debug().Msgf("stopped network: %+v", key.server) } return nil @@ -336,13 +338,13 @@ func (s *service) StopNetworkIfRunning(key handlerKey) error { func (s *service) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetwork, error) { network, err := s.repo.GetNetworkByID(ctx, id) if err != nil { - log.Error().Err(err).Msgf("failed to get network: %v", id) + s.log.Error().Err(err).Msgf("failed to get network: %v", id) return nil, err } channels, err := s.repo.ListChannels(network.ID) if err != nil { - log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server) + s.log.Error().Err(err).Msgf("failed to list channels for network %q", network.Server) return nil, err } network.Channels = append(network.Channels, channels...) @@ -353,7 +355,7 @@ func (s *service) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) { networks, err := s.repo.ListNetworks(ctx) if err != nil { - log.Error().Err(err).Msgf("failed to list networks: %v", err) + s.log.Error().Err(err).Msgf("failed to list networks: %v", err) return nil, err } @@ -362,7 +364,7 @@ func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) for _, n := range networks { channels, err := s.repo.ListChannels(n.ID) if err != nil { - log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err) + s.log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err) return nil, err } n.Channels = append(n.Channels, channels...) @@ -376,7 +378,7 @@ func (s *service) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetworkWithHealth, error) { networks, err := s.repo.ListNetworks(ctx) if err != nil { - log.Error().Err(err).Msgf("failed to list networks: %v", err) + s.log.Error().Err(err).Msgf("failed to list networks: %v", err) return nil, err } @@ -410,7 +412,7 @@ func (s *service) GetNetworksWithHealth(ctx context.Context) ([]domain.IrcNetwor channels, err := s.repo.ListChannels(n.ID) if err != nil { - log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err) + s.log.Error().Msgf("failed to list channels for network %q: %v", n.Server, err) return nil, err } @@ -457,7 +459,7 @@ func (s *service) DeleteNetwork(ctx context.Context, id int64) error { return err } - log.Debug().Msgf("delete network: %v", id) + s.log.Debug().Msgf("delete network: %v", id) // Remove network and handler //if err = s.StopNetwork(network.Server); err != nil { @@ -483,7 +485,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) if err := s.repo.UpdateNetwork(ctx, network); err != nil { return err } - log.Debug().Msgf("irc.service: update network: %+v", network) + s.log.Debug().Msgf("irc.service: update network: %+v", network) // stop or start network // TODO get current state to see if enabled or not? @@ -493,7 +495,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) // if channels len : changes - join or leave err := s.checkIfNetworkRestartNeeded(network) if err != nil { - log.Error().Stack().Err(err).Msgf("could not restart network: %+v", network.Name) + s.log.Error().Stack().Err(err).Msgf("could not restart network: %+v", network.Name) return fmt.Errorf("could not restart network: %v", network.Name) } @@ -501,7 +503,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) // take into account multiple channels per network err := s.StopAndRemoveNetwork(handlerKey{network.Server, network.NickServ.Account}) if err != nil { - log.Error().Stack().Err(err).Msgf("could not stop network: %+v", network.Name) + s.log.Error().Stack().Err(err).Msgf("could not stop network: %+v", network.Name) return fmt.Errorf("could not stop network: %v", network.Name) } } @@ -512,7 +514,7 @@ func (s *service) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork) error { existingNetwork, err := s.repo.CheckExistingNetwork(ctx, network) if err != nil { - log.Error().Err(err).Msg("could not check for existing network") + s.log.Error().Err(err).Msg("could not check for existing network") return err } @@ -520,12 +522,12 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork) if err := s.repo.StoreNetwork(network); err != nil { return err } - log.Debug().Msgf("store network: %+v", network) + s.log.Debug().Msgf("store network: %+v", network) if network.Channels != nil { for _, channel := range network.Channels { if err := s.repo.StoreChannel(network.ID, &channel); err != nil { - log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query") + s.log.Error().Stack().Err(err).Msg("irc.storeChannel: error executing query") return errors.Wrap(err, "error storing channel on network") //return err } @@ -538,7 +540,7 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork) // get channels for existing network existingChannels, err := s.repo.ListChannels(existingNetwork.ID) if err != nil { - log.Error().Err(err).Msgf("failed to list channels for network %q", existingNetwork.Server) + s.log.Error().Err(err).Msgf("failed to list channels for network %q", existingNetwork.Server) } existingNetwork.Channels = existingChannels @@ -561,7 +563,7 @@ func (s *service) StoreNetwork(ctx context.Context, network *domain.IrcNetwork) err := s.checkIfNetworkRestartNeeded(existingNetwork) if err != nil { - log.Error().Err(err).Msgf("could not restart network: %+v", existingNetwork.Name) + s.log.Error().Err(err).Msgf("could not restart network: %+v", existingNetwork.Name) return fmt.Errorf("could not restart network: %v", existingNetwork.Name) } } diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 538825f..9ae14bc 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -2,71 +2,144 @@ package logger import ( "io" - stdlog "log" "os" "time" "github.com/autobrr/autobrr/internal/domain" - "github.com/dcarbone/zadapters/zstdlog" "github.com/r3labs/sse/v2" "github.com/rs/zerolog" - "github.com/rs/zerolog/log" "github.com/rs/zerolog/pkgerrors" "gopkg.in/natefinch/lumberjack.v2" ) -var ( - StdLogger *stdlog.Logger - StdLeveledLogger *stdlog.Logger -) +// Logger interface +type Logger interface { + Log() *zerolog.Event + Fatal() *zerolog.Event + Err(err error) *zerolog.Event + Error() *zerolog.Event + Warn() *zerolog.Event + Info() *zerolog.Event + Trace() *zerolog.Event + Debug() *zerolog.Event + With() zerolog.Context + RegisterSSEHook(sse *sse.Server) + SetLogLevel(level string) +} -func Setup(cfg domain.Config, sse *sse.Server) { +// DefaultLogger default logging controller +type DefaultLogger struct { + log zerolog.Logger + level zerolog.Level + writers []io.Writer +} +func New(cfg *domain.Config) Logger { + l := &DefaultLogger{ + writers: make([]io.Writer, 0), + level: zerolog.DebugLevel, + } + + // set log level + l.SetLogLevel(cfg.LogLevel) + + // use pretty logging for dev only + if cfg.Version == "dev" { + // setup console writer + consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339} + + l.writers = append(l.writers, consoleWriter) + } else { + // default to stderr + l.writers = append(l.writers, os.Stderr) + } + + if cfg.LogPath != "" { + l.writers = append(l.writers, + &lumberjack.Logger{ + Filename: cfg.LogPath, + MaxSize: 50, // megabytes + MaxBackups: 3, + }, + ) + } + + // set some defaults zerolog.TimeFieldFormat = time.RFC3339 zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack - switch cfg.LogLevel { + // init new logger + l.log = zerolog.New(io.MultiWriter(l.writers...)).With().Stack().Logger() + + return l +} + +func (l *DefaultLogger) RegisterSSEHook(sse *sse.Server) { + l.log = l.log.Hook(&ServerSentEventHook{sse: sse}) +} + +func (l *DefaultLogger) SetLogLevel(level string) { + switch level { case "INFO": + l.level = zerolog.InfoLevel zerolog.SetGlobalLevel(zerolog.InfoLevel) case "DEBUG": + l.level = zerolog.DebugLevel zerolog.SetGlobalLevel(zerolog.DebugLevel) case "ERROR": - zerolog.SetGlobalLevel(zerolog.ErrorLevel) + l.level = zerolog.ErrorLevel case "WARN": - zerolog.SetGlobalLevel(zerolog.WarnLevel) + l.level = zerolog.WarnLevel case "TRACE": + l.level = zerolog.TraceLevel zerolog.SetGlobalLevel(zerolog.TraceLevel) default: - zerolog.SetGlobalLevel(zerolog.ErrorLevel) + l.level = zerolog.Disabled } - - // setup console writer - consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339} - - writers := io.MultiWriter(consoleWriter) - - // if logPath set create file writer - if cfg.LogPath != "" { - fileWriter := &lumberjack.Logger{ - Filename: cfg.LogPath, - MaxSize: 100, // megabytes - MaxBackups: 3, - } - - // overwrite writers - writers = io.MultiWriter(consoleWriter, fileWriter) - } - - log.Logger = log.Hook(&ServerSentEventHook{sse: sse}) - log.Logger = log.Output(writers) - - // init a logger to use - //log := zerolog.New(os.Stdout) - - // creates a *log.Logger with no level prefix - StdLogger = zstdlog.NewStdLogger(log.Logger) - - // creates a *log.Logger with a level prefix - StdLeveledLogger = zstdlog.NewStdLoggerWithLevel(log.Logger, zerolog.TraceLevel) +} + +// Log log something at fatal level. +func (l *DefaultLogger) Log() *zerolog.Event { + return l.log.Log().Time("time", time.Now()) +} + +// Fatal log something at fatal level. This will panic! +func (l *DefaultLogger) Fatal() *zerolog.Event { + return l.log.Fatal().Time("time", time.Now()) +} + +// Error log something at Error level +func (l *DefaultLogger) Error() *zerolog.Event { + return l.log.Error().Time("time", time.Now()) +} + +// Err log something at Err level +func (l *DefaultLogger) Err(err error) *zerolog.Event { + return l.log.Err(err).Time("time", time.Now()) +} + +// Warn log something at warning level. +func (l *DefaultLogger) Warn() *zerolog.Event { + return l.log.Warn().Time("time", time.Now()) +} + +// Info log something at fatal level. +func (l *DefaultLogger) Info() *zerolog.Event { + return l.log.Info().Time("time", time.Now()) +} + +// Debug log something at debug level. +func (l *DefaultLogger) Debug() *zerolog.Event { + return l.log.Debug().Time("time", time.Now()) +} + +// Trace log something at fatal level. This will panic! +func (l *DefaultLogger) Trace() *zerolog.Event { + return l.log.Trace().Time("time", time.Now()) +} + +// With log with context +func (l *DefaultLogger) With() zerolog.Context { + return l.log.With() } diff --git a/internal/notification/discord.go b/internal/notification/discord.go index 36aae6b..dba4998 100644 --- a/internal/notification/discord.go +++ b/internal/notification/discord.go @@ -10,8 +10,6 @@ import ( "time" "github.com/autobrr/autobrr/internal/domain" - - "github.com/rs/zerolog/log" ) type DiscordMessage struct { @@ -33,7 +31,7 @@ type DiscordEmbedsFields struct { Inline bool `json:"inline,omitempty"` } -func discordNotification(event domain.EventsReleasePushed, webhookURL string) { +func (s *service) discordNotification(event domain.EventsReleasePushed, webhookURL string) { t := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, @@ -120,13 +118,13 @@ func discordNotification(event domain.EventsReleasePushed, webhookURL string) { jsonData, err := json.Marshal(m) if err != nil { - log.Error().Err(err).Msgf("discord client could not marshal data: %v", m) + s.log.Error().Err(err).Msgf("discord client could not marshal data: %v", m) return } req, err := http.NewRequest(http.MethodPost, webhookURL, bytes.NewBuffer(jsonData)) if err != nil { - log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName) + s.log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName) return } @@ -135,13 +133,13 @@ func discordNotification(event domain.EventsReleasePushed, webhookURL string) { res, err := client.Do(req) if err != nil { - log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName) + s.log.Error().Err(err).Msgf("discord client request error: %v", event.ReleaseName) return } defer res.Body.Close() - log.Debug().Msg("notification successfully sent to discord") + s.log.Debug().Msg("notification successfully sent to discord") return } diff --git a/internal/notification/service.go b/internal/notification/service.go index b4c9b2d..47bd41c 100644 --- a/internal/notification/service.go +++ b/internal/notification/service.go @@ -3,7 +3,10 @@ package notification import ( "context" "fmt" + "github.com/autobrr/autobrr/internal/domain" + "github.com/autobrr/autobrr/internal/logger" + "github.com/containrrr/shoutrrr" t "github.com/containrrr/shoutrrr/pkg/types" ) @@ -19,11 +22,13 @@ type Service interface { } type service struct { + log logger.Logger repo domain.NotificationRepo } -func NewService(repo domain.NotificationRepo) Service { +func NewService(log logger.Logger, repo domain.NotificationRepo) Service { return &service{ + log: log, repo: repo, } } @@ -132,7 +137,7 @@ func (s *service) send(notifications []domain.Notification, event domain.EventsR if evt == string(event.Status) { switch n.Type { case domain.NotificationTypeDiscord: - go discordNotification(event, n.Webhook) + go s.discordNotification(event, n.Webhook) default: return nil } diff --git a/internal/release/service.go b/internal/release/service.go index 08b7d85..9b5e43e 100644 --- a/internal/release/service.go +++ b/internal/release/service.go @@ -8,8 +8,7 @@ import ( "github.com/autobrr/autobrr/internal/action" "github.com/autobrr/autobrr/internal/domain" "github.com/autobrr/autobrr/internal/filter" - - "github.com/rs/zerolog/log" + "github.com/autobrr/autobrr/internal/logger" ) type Service interface { @@ -30,14 +29,16 @@ type actionClientTypeKey struct { } type service struct { + log logger.Logger repo domain.ReleaseRepo actionSvc action.Service filterSvc filter.Service } -func NewService(repo domain.ReleaseRepo, actionSvc action.Service, filterSvc filter.Service) Service { +func NewService(log logger.Logger, repo domain.ReleaseRepo, actionSvc action.Service, filterSvc filter.Service) Service { return &service{ + log: log, repo: repo, actionSvc: actionSvc, filterSvc: filterSvc, @@ -85,7 +86,7 @@ func (s *service) Process(release *domain.Release) { // get filters by priority filters, err := s.filterSvc.FindByIndexerIdentifier(release.Indexer) if err != nil { - log.Error().Err(err).Msgf("announce.Service.Process: error finding filters for indexer: %v", release.Indexer) + s.log.Error().Err(err).Msgf("announce.Service.Process: error finding filters for indexer: %v", release.Indexer) return } @@ -109,23 +110,23 @@ func (s *service) Process(release *domain.Release) { // test filter match, err := s.filterSvc.CheckFilter(f, release) if err != nil { - log.Error().Err(err).Msg("announce.Service.Process: could not find filter") + s.log.Error().Err(err).Msg("announce.Service.Process: could not find filter") return } if !match { - log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, no match", release.Indexer, release.Filter.Name, release.TorrentName) + s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, no match", release.Indexer, release.Filter.Name, release.TorrentName) continue } - log.Info().Msgf("Matched '%v' (%v) for %v", release.TorrentName, release.Filter.Name, release.Indexer) + s.log.Info().Msgf("Matched '%v' (%v) for %v", release.TorrentName, release.Filter.Name, release.Indexer) // save release here to only save those with rejections from actions instead of all releases if release.ID == 0 { release.FilterStatus = domain.ReleaseStatusFilterApproved err = s.Store(context.Background(), release) if err != nil { - log.Error().Err(err).Msgf("announce.Service.Process: error writing release to database: %+v", release) + s.log.Error().Err(err).Msgf("announce.Service.Process: error writing release to database: %+v", release) return } } @@ -133,7 +134,7 @@ func (s *service) Process(release *domain.Release) { // sleep for the delay period specified in the filter before running actions delay := release.Filter.Delay if delay > 0 { - log.Debug().Msgf("Delaying processing of '%v' (%v) for %v by %d seconds as specified in the filter", release.TorrentName, release.Filter.Name, release.Indexer, delay) + s.log.Debug().Msgf("Delaying processing of '%v' (%v) for %v by %d seconds as specified in the filter", release.TorrentName, release.Filter.Name, release.Indexer, delay) time.Sleep(time.Duration(delay) * time.Second) } @@ -143,22 +144,22 @@ func (s *service) Process(release *domain.Release) { for _, a := range release.Filter.Actions { // only run enabled actions if !a.Enabled { - log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action '%v' not enabled, skip", release.Indexer, release.Filter.Name, release.TorrentName, a.Name) + s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action '%v' not enabled, skip", release.Indexer, release.Filter.Name, release.TorrentName, a.Name) continue } - log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v , run action: %v", release.Indexer, release.Filter.Name, release.TorrentName, a.Name) + s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v , run action: %v", release.Indexer, release.Filter.Name, release.TorrentName, a.Name) // keep track of action clients to avoid sending the same thing all over again _, tried := triedActionClients[actionClientTypeKey{Type: a.Type, ClientID: a.ClientID}] if tried { - log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action client already tried, skip", release.Indexer, release.Filter.Name, release.TorrentName) + s.log.Trace().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v action client already tried, skip", release.Indexer, release.Filter.Name, release.TorrentName) continue } rejections, err = s.actionSvc.RunAction(a, *release) if err != nil { - log.Error().Stack().Err(err).Msgf("announce.Service.Process: error running actions for filter: %v", release.Filter.Name) + s.log.Error().Stack().Err(err).Msgf("announce.Service.Process: error running actions for filter: %v", release.Filter.Name) continue } @@ -167,7 +168,7 @@ func (s *service) Process(release *domain.Release) { triedActionClients[actionClientTypeKey{Type: a.Type, ClientID: a.ClientID}] = struct{}{} // log something and fire events - log.Debug().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, rejected: %v", release.Indexer, release.Filter.Name, release.TorrentName, strings.Join(rejections, ", ")) + s.log.Debug().Msgf("announce.Service.Process: indexer: %v, filter: %v release: %v, rejected: %v", release.Indexer, release.Filter.Name, release.TorrentName, strings.Join(rejections, ", ")) } // if no rejections consider action approved, run next diff --git a/internal/scheduler/service.go b/internal/scheduler/service.go index a771a4a..10e0957 100644 --- a/internal/scheduler/service.go +++ b/internal/scheduler/service.go @@ -3,8 +3,9 @@ package scheduler import ( "fmt" + "github.com/autobrr/autobrr/internal/logger" + "github.com/robfig/cron/v3" - "github.com/rs/zerolog/log" ) type Service interface { @@ -16,13 +17,15 @@ type Service interface { } type service struct { + log logger.Logger cron *cron.Cron jobs map[string]cron.EntryID } -func NewService() Service { +func NewService(log logger.Logger) Service { return &service{ + log: log, cron: cron.New(cron.WithChain( cron.Recover(cron.DefaultLogger), )), @@ -31,14 +34,14 @@ func NewService() Service { } func (s *service) Start() { - log.Debug().Msg("scheduler.Start") + s.log.Debug().Msg("scheduler.Start") s.cron.Start() return } func (s *service) Stop() { - log.Debug().Msg("scheduler.Stop") + s.log.Debug().Msg("scheduler.Stop") s.cron.Stop() return } @@ -51,7 +54,7 @@ func (s *service) AddJob(job cron.Job, interval string, identifier string) (int, return 0, fmt.Errorf("scheduler: add job failed: %w", err) } - log.Debug().Msgf("scheduler.AddJob: job successfully added: %v", id) + s.log.Debug().Msgf("scheduler.AddJob: job successfully added: %v", id) // add to job map s.jobs[identifier] = id @@ -75,7 +78,7 @@ func (s *service) RemoveJobByIdentifier(id string) error { return nil } - log.Debug().Msgf("scheduler.Remove: removing job: %v", id) + s.log.Debug().Msgf("scheduler.Remove: removing job: %v", id) // remove from cron s.cron.Remove(v) diff --git a/internal/server/server.go b/internal/server/server.go index 74b60fc..31ffc70 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -6,12 +6,12 @@ import ( "github.com/autobrr/autobrr/internal/feed" "github.com/autobrr/autobrr/internal/indexer" "github.com/autobrr/autobrr/internal/irc" + "github.com/autobrr/autobrr/internal/logger" "github.com/autobrr/autobrr/internal/scheduler" - - "github.com/rs/zerolog/log" ) type Server struct { + log logger.Logger Hostname string Port int @@ -24,8 +24,9 @@ type Server struct { lock sync.Mutex } -func NewServer(ircSvc irc.Service, indexerSvc indexer.Service, feedSvc feed.Service, scheduler scheduler.Service) *Server { +func NewServer(log logger.Logger, ircSvc irc.Service, indexerSvc indexer.Service, feedSvc feed.Service, scheduler scheduler.Service) *Server { return &Server{ + log: log, indexerService: indexerSvc, ircService: ircSvc, feedService: feedSvc, @@ -34,14 +35,14 @@ func NewServer(ircSvc irc.Service, indexerSvc indexer.Service, feedSvc feed.Serv } func (s *Server) Start() error { - log.Info().Msgf("Starting server. Listening on %v:%v", s.Hostname, s.Port) + s.log.Info().Msgf("Starting server. Listening on %v:%v", s.Hostname, s.Port) // start cron scheduler s.scheduler.Start() // instantiate indexers if err := s.indexerService.Start(); err != nil { - log.Error().Err(err).Msg("Could not start indexer service") + s.log.Error().Err(err).Msg("Could not start indexer service") return err } @@ -50,14 +51,14 @@ func (s *Server) Start() error { // start torznab feeds if err := s.feedService.Start(); err != nil { - log.Error().Err(err).Msg("Could not start feed service") + s.log.Error().Err(err).Msg("Could not start feed service") } return nil } func (s *Server) Shutdown() { - log.Info().Msg("Shutting down server") + s.log.Info().Msg("Shutting down server") // stop all irc handlers s.ircService.StopHandlers() diff --git a/internal/user/service.go b/internal/user/service.go index 5bf38e5..3105d98 100644 --- a/internal/user/service.go +++ b/internal/user/service.go @@ -3,6 +3,7 @@ package user import ( "context" "errors" + "github.com/autobrr/autobrr/internal/domain" ) diff --git a/pkg/ggn/ggn.go b/pkg/ggn/ggn.go index b471e63..148c30c 100644 --- a/pkg/ggn/ggn.go +++ b/pkg/ggn/ggn.go @@ -13,7 +13,6 @@ import ( "github.com/autobrr/autobrr/internal/domain" - "github.com/rs/zerolog/log" "golang.org/x/time/rate" ) @@ -160,8 +159,7 @@ func (c *client) Do(req *http.Request) (*http.Response, error) { func (c *client) get(url string) (*http.Response, error) { req, err := http.NewRequest(http.MethodGet, url, http.NoBody) if err != nil { - log.Error().Err(err).Msgf("ggn client request error : %v", url) - return nil, err + return nil, errors.New(fmt.Sprintf("ggn client request error : %v", url)) } req.Header.Add("X-API-Key", c.APIKey) @@ -169,8 +167,7 @@ func (c *client) get(url string) (*http.Response, error) { res, err := c.Do(req) if err != nil { - log.Error().Err(err).Msgf("ggn client request error : %v", url) - return nil, err + return nil, errors.New(fmt.Sprintf("ggn client request error : %v", url)) } if res.StatusCode == http.StatusUnauthorized { diff --git a/pkg/lidarr/client.go b/pkg/lidarr/client.go index 9eb40c7..a9b2b7e 100644 --- a/pkg/lidarr/client.go +++ b/pkg/lidarr/client.go @@ -9,8 +9,6 @@ import ( "net/http" "net/url" "path" - - "github.com/rs/zerolog/log" ) func (c *client) get(endpoint string) (int, []byte, error) { @@ -20,8 +18,7 @@ func (c *client) get(endpoint string) (int, []byte, error) { req, err := http.NewRequest(http.MethodGet, reqUrl, http.NoBody) if err != nil { - log.Error().Err(err).Msgf("lidarr client request error : %v", reqUrl) - return 0, nil, err + return 0, nil, errors.New(fmt.Sprintf("lidarr client request error : %v", reqUrl)) } if c.config.BasicAuth { @@ -32,7 +29,6 @@ func (c *client) get(endpoint string) (int, []byte, error) { resp, err := c.http.Do(req) if err != nil { - log.Error().Err(err).Msgf("lidarr client.get request error: %v", reqUrl) return 0, nil, fmt.Errorf("lidarr.http.Do(req): %w", err) } @@ -53,14 +49,12 @@ func (c *client) post(endpoint string, data interface{}) (*http.Response, error) jsonData, err := json.Marshal(data) if err != nil { - log.Error().Err(err).Msgf("lidarr client could not marshal data: %v", reqUrl) - return nil, err + return nil, fmt.Errorf("lidarr client could not marshal data: %v", reqUrl) } req, err := http.NewRequest(http.MethodPost, reqUrl, bytes.NewBuffer(jsonData)) if err != nil { - log.Error().Err(err).Msgf("lidarr client request error: %v", reqUrl) - return nil, err + return nil, fmt.Errorf("lidarr client request error: %v", reqUrl) } if c.config.BasicAuth { @@ -73,16 +67,13 @@ func (c *client) post(endpoint string, data interface{}) (*http.Response, error) res, err := c.http.Do(req) if err != nil { - log.Error().Err(err).Msgf("lidarr client request error: %v", reqUrl) - return nil, err + return nil, fmt.Errorf("lidarr client request error: %v", reqUrl) } // validate response if res.StatusCode == http.StatusUnauthorized { - log.Error().Err(err).Msgf("lidarr client bad request: %v", reqUrl) - return nil, errors.New("unauthorized: bad credentials") + return nil, errors.New("lidarr: unauthorized: bad credentials") } else if res.StatusCode != http.StatusOK { - log.Error().Err(err).Msgf("lidarr client request error: %v", reqUrl) return nil, errors.New("lidarr: bad request") } @@ -97,14 +88,12 @@ func (c *client) postBody(endpoint string, data interface{}) (int, []byte, error jsonData, err := json.Marshal(data) if err != nil { - log.Error().Err(err).Msgf("lidarr client could not marshal data: %v", reqUrl) - return 0, nil, err + return 0, nil, fmt.Errorf("lidarr client could not marshal data: %v", reqUrl) } req, err := http.NewRequest(http.MethodPost, reqUrl, bytes.NewBuffer(jsonData)) if err != nil { - log.Error().Err(err).Msgf("lidarr client request error: %v", reqUrl) - return 0, nil, err + return 0, nil, fmt.Errorf("lidarr client request error: %v", reqUrl) } if c.config.BasicAuth { @@ -115,7 +104,6 @@ func (c *client) postBody(endpoint string, data interface{}) (int, []byte, error resp, err := c.http.Do(req) if err != nil { - log.Error().Err(err).Msgf("lidarr client request error: %v", reqUrl) return 0, nil, fmt.Errorf("lidarr.http.Do(req): %w", err) } diff --git a/pkg/lidarr/lidarr.go b/pkg/lidarr/lidarr.go index 2fe4385..6f36e62 100644 --- a/pkg/lidarr/lidarr.go +++ b/pkg/lidarr/lidarr.go @@ -3,11 +3,10 @@ package lidarr import ( "encoding/json" "errors" + "fmt" "net/http" "strings" "time" - - "github.com/rs/zerolog/log" ) type Config struct { @@ -69,48 +68,43 @@ type SystemStatusResponse struct { func (c *client) Test() (*SystemStatusResponse, error) { status, res, err := c.get("system/status") if err != nil { - log.Error().Stack().Err(err).Msg("lidarr client get error") - return nil, err + return nil, fmt.Errorf("lidarr client get error: %w", err) } if status == http.StatusUnauthorized { return nil, errors.New("unauthorized: bad credentials") } - log.Trace().Msgf("lidarr system/status response status: %v body: %v", status, string(res)) + //log.Trace().Msgf("lidarr system/status response status: %v body: %v", status, string(res)) response := SystemStatusResponse{} err = json.Unmarshal(res, &response) if err != nil { - log.Error().Stack().Err(err).Msg("lidarr client error json unmarshal") - return nil, err + return nil, fmt.Errorf("lidarr client error json unmarshal: %w", err) } return &response, nil } func (c *client) Push(release Release) ([]string, error) { - status, res, err := c.postBody("release/push", release) + _, res, err := c.postBody("release/push", release) if err != nil { - log.Error().Stack().Err(err).Msg("lidarr client post error") - return nil, err + return nil, fmt.Errorf("lidarr client post error: %w", err) } - log.Trace().Msgf("lidarr release/push response status: %v body: %v", status, string(res)) + //log.Trace().Msgf("lidarr release/push response status: %v body: %v", status, string(res)) pushResponse := PushResponse{} err = json.Unmarshal(res, &pushResponse) if err != nil { - log.Error().Stack().Err(err).Msg("lidarr client error json unmarshal") - return nil, err + return nil, fmt.Errorf("lidarr client error json unmarshal: %w", err) } // log and return if rejected if pushResponse.Rejected { rejections := strings.Join(pushResponse.Rejections, ", ") - log.Trace().Msgf("lidarr push rejected: %s - reasons: %q", release.Title, rejections) - return pushResponse.Rejections, nil + return pushResponse.Rejections, fmt.Errorf("lidarr push rejected: %s - reasons: %q: err %w", release.Title, rejections, err) } return nil, nil diff --git a/pkg/ptp/ptp.go b/pkg/ptp/ptp.go index b4aaede..ad8f986 100644 --- a/pkg/ptp/ptp.go +++ b/pkg/ptp/ptp.go @@ -12,7 +12,6 @@ import ( "github.com/autobrr/autobrr/internal/domain" - "github.com/rs/zerolog/log" "golang.org/x/time/rate" ) @@ -100,8 +99,7 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) { func (c *Client) get(url string) (*http.Response, error) { req, err := http.NewRequest(http.MethodGet, url, http.NoBody) if err != nil { - log.Error().Err(err).Msgf("ptp client request error : %v", url) - return nil, err + return nil, fmt.Errorf("ptp client request error : %v", url) } req.Header.Add("ApiUser", c.APIUser) @@ -110,8 +108,7 @@ func (c *Client) get(url string) (*http.Response, error) { res, err := c.Do(req) if err != nil { - log.Error().Err(err).Msgf("ptp client request error : %v", url) - return nil, err + return nil, fmt.Errorf("ptp client request error : %v", url) } if res.StatusCode == http.StatusUnauthorized {