diff --git a/.golangci.yml b/.golangci.yml index 9688b559..8e144ce8 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -9,6 +9,11 @@ linters: - errorlint - gci - gocritic + - goimports - misspell - typecheck - wrapcheck + +linters-settings: + goimports: + local-prefixes: github.com/release-argus/Argus \ No newline at end of file diff --git a/cmd/argus/main.go b/cmd/argus/main.go index bce09732..7641f4c7 100644 --- a/cmd/argus/main.go +++ b/cmd/argus/main.go @@ -22,16 +22,16 @@ import ( "flag" "fmt" + _ "modernc.org/sqlite" + cfg "github.com/release-argus/Argus/config" "github.com/release-argus/Argus/db" "github.com/release-argus/Argus/testing" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web" - _ "modernc.org/sqlite" ) var ( - jLog util.JLog configFile = flag.String("config.file", "config.yml", "Argus configuration file path.") configCheckFlag = flag.Bool("config.check", false, "Print the fully-parsed config.") testCommandsFlag = flag.String("test.commands", "", "Put the name of the Service to test the `commands` of.") @@ -48,19 +48,19 @@ func main() { flag.Visit(func(f *flag.Flag) { flagset[f.Name] = true }) var config cfg.Config - config.Load(*configFile, &flagset, &jLog) - jLog.SetTimestamps(*config.Settings.LogTimestamps()) - jLog.SetLevel(config.Settings.LogLevel()) + config.Load(*configFile, &flagset) + logutil.Log.SetTimestamps(*config.Settings.LogTimestamps()) + logutil.Log.SetLevel(config.Settings.LogLevel()) // config.check config.Print(configCheckFlag) // test.* - testing.CommandTest(testCommandsFlag, &config, &jLog) - testing.NotifyTest(testNotifyFlag, &config, &jLog) - testing.ServiceTest(testServiceFlag, &config, &jLog) + testing.CommandTest(testCommandsFlag, &config) + testing.NotifyTest(testNotifyFlag, &config) + testing.ServiceTest(testServiceFlag, &config) // Count of active services to monitor (if log level INFO or above). - if jLog.Level > 1 { + if logutil.Log.Level > 1 { // Count active services. serviceCount := len(config.Order) for _, key := range config.Order { @@ -71,7 +71,7 @@ func main() { // Log active count. msg := fmt.Sprintf("Found %d services to monitor:", serviceCount) - jLog.Info(msg, util.LogFrom{}, true) + logutil.Log.Info(msg, logutil.LogFrom{}, true) // Log names of active services. for _, key := range config.Order { @@ -82,11 +82,11 @@ func main() { } // Setup DB and last known service versions. - db.Run(&config, &jLog) + db.Run(&config) // Track all targets for changes in version and act on any found changes. go config.Service.Track(&config.Order, &config.OrderMutex) // Web server. - web.Run(&config, &jLog) + web.Run(&config) } diff --git a/cmd/argus/main_test.go b/cmd/argus/main_test.go index ba5b4d88..161f5de4 100644 --- a/cmd/argus/main_test.go +++ b/cmd/argus/main_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ import ( "time" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func resetFlags() { @@ -37,8 +37,8 @@ func resetFlags() { func TestTheMain(t *testing.T) { // GIVEN different Configs to test - jLog = *util.NewJLog("WARN", false) - jLog.Testing = true + logutil.Init("WARN", false) + logutil.Log.Testing = true tests := map[string]struct { file func(path string, t *testing.T) outputContains *[]string diff --git a/command/command.go b/command/command.go index a2000fa9..b72cf032 100644 --- a/command/command.go +++ b/command/command.go @@ -24,11 +24,12 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web/metric" ) // Exec will execute every `Command` for the controller. -func (c *Controller) Exec(logFrom util.LogFrom) error { +func (c *Controller) Exec(logFrom logutil.LogFrom) error { if c == nil || c.Command == nil || len(*c.Command) == 0 { return nil } @@ -59,7 +60,7 @@ func (c *Controller) Exec(logFrom util.LogFrom) error { } // ExecIndex will execute the `Command` at the given index. -func (c *Controller) ExecIndex(logFrom util.LogFrom, index int) error { +func (c *Controller) ExecIndex(logFrom logutil.LogFrom, index int) error { if index >= len(*c.Command) { return nil } @@ -100,17 +101,17 @@ func (c *Controller) ExecIndex(logFrom util.LogFrom, index int) error { } // Exec this Command and return any errors encountered. -func (c *Command) Exec(logFrom util.LogFrom) error { - jLog.Info( +func (c *Command) Exec(logFrom logutil.LogFrom) error { + logutil.Log.Info( fmt.Sprintf("Executing '%s'", c), logFrom, true) //#nosec G204 -- Command is user defined. out, err := exec.Command((*c)[0], (*c)[1:]...).Output() if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) } else { - jLog.Info(string(out), logFrom, string(out) != "") + logutil.Log.Info(string(out), logFrom, string(out) != "") } //nolint:wrapcheck diff --git a/command/command_test.go b/command/command_test.go index bac21b26..1f973eba 100644 --- a/command/command_test.go +++ b/command/command_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestCommand_ApplyTemplate(t *testing.T) { @@ -94,7 +95,7 @@ func TestCommand_Exec(t *testing.T) { releaseStdout := test.CaptureStdout() // WHEN Exec is called on it - err := tc.cmd.Exec(util.LogFrom{}) + err := tc.cmd.Exec(logutil.LogFrom{}) // THEN the stdout is expected if util.ErrorToString(err) != util.ErrorToString(tc.err) { @@ -152,7 +153,7 @@ func TestController_ExecIndex(t *testing.T) { releaseStdout := test.CaptureStdout() // WHEN the Command @index is executed - err := controller.ExecIndex(util.LogFrom{}, tc.index) + err := controller.ExecIndex(logutil.LogFrom{}, tc.index) // THEN the stdout is expected // err @@ -219,7 +220,7 @@ func TestController_Exec(t *testing.T) { if tc.nilController { controller = nil } - err := controller.Exec(util.LogFrom{}) + err := controller.Exec(logutil.LogFrom{}) // THEN the stdout is expected // err diff --git a/command/help_test.go b/command/help_test.go index 58110677..966b39eb 100644 --- a/command/help_test.go +++ b/command/help_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,14 +22,13 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - mainJLog := util.NewJLog("DEBUG", false) - mainJLog.Testing = true - LogInit(mainJLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/command/init.go b/command/init.go index 83a7ac9a..4b04f728 100644 --- a/command/init.go +++ b/command/init.go @@ -26,11 +26,6 @@ import ( "github.com/release-argus/Argus/web/metric" ) -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} - // Init the Command Controller. func (c *Controller) Init( serviceStatus *status.Status, diff --git a/command/init_test.go b/command/init_test.go index cf965bf8..549309de 100644 --- a/command/init_test.go +++ b/command/init_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/release-argus/Argus/notify/shoutrrr" shoutrrr_test "github.com/release-argus/Argus/notify/shoutrrr/test" "github.com/release-argus/Argus/service/status" diff --git a/command/types.go b/command/types.go index 6b7051d9..85d83cc2 100644 --- a/command/types.go +++ b/command/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,11 +22,6 @@ import ( "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/status" - "github.com/release-argus/Argus/util" -) - -var ( - jLog *util.JLog ) // Slice mapping of WebHook. diff --git a/config/defaults.go b/config/defaults.go index e2da3327..8a0b4218 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import ( "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -70,9 +71,9 @@ func (d *Defaults) MapEnvToStruct() { } if err != nil { - jLog.Fatal( + logutil.Log.Fatal( "One or more 'ARGUS_' environment variables are invalid:\n"+err.Error(), - util.LogFrom{}, true) + logutil.LogFrom{}, true) } } diff --git a/config/edit.go b/config/edit.go index 577e6cf5..54e5e834 100644 --- a/config/edit.go +++ b/config/edit.go @@ -21,19 +21,20 @@ import ( dbtype "github.com/release-argus/Argus/db/types" "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // AddService to the config (or replace/rename an existing service). func (c *Config) AddService(oldServiceID string, newService *service.Service) error { c.OrderMutex.Lock() defer c.OrderMutex.Unlock() - logFrom := util.LogFrom{Primary: "AddService"} + logFrom := logutil.LogFrom{Primary: "AddService"} // Check a service does not already exist with the new id/name, if the name is changing. if oldServiceID != newService.ID && (c.Service[newService.ID] != nil || c.ServiceWithNameExists(newService.ID, oldServiceID)) { err := fmt.Errorf("service %q already exists", newService.ID) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return err } @@ -46,7 +47,7 @@ func (c *Config) AddService(oldServiceID string, newService *service.Service) er !c.Service[oldServiceID].Status.SameVersions(&newService.Status) // New service. if oldServiceID == "" || c.Service[oldServiceID] == nil { - jLog.Info("Adding service", logFrom, true) + logutil.Log.Info("Adding service", logFrom, true) c.Order = append(c.Order, newService.ID) // Create the service map if it doesn't exist. //nolint:typecheck @@ -58,7 +59,7 @@ func (c *Config) AddService(oldServiceID string, newService *service.Service) er } else { // Keeping the same ID. if oldServiceID == newService.ID { - jLog.Info("Replacing service", logFrom, true) + logutil.Log.Info("Replacing service", logFrom, true) // Delete the old service. c.Service[oldServiceID].PrepDelete(false) @@ -120,9 +121,9 @@ func (c *Config) RenameService(oldService string, newService *service.Service) { return } - jLog.Info( + logutil.Log.Info( fmt.Sprintf("%q", newService.ID), - util.LogFrom{Primary: "RenameService", Secondary: oldService}, + logutil.LogFrom{Primary: "RenameService", Secondary: oldService}, true) // Replace the service in the order/config. c.Order = util.ReplaceElement(c.Order, oldService, newService.ID) @@ -147,9 +148,9 @@ func (c *Config) DeleteService(serviceID string) { return } - jLog.Info( + logutil.Log.Info( "Deleting service", - util.LogFrom{Primary: "DeleteService", Secondary: serviceID}, + logutil.LogFrom{Primary: "DeleteService", Secondary: serviceID}, true) // Remove the service from the Order. c.Order = util.RemoveElement(c.Order, serviceID) diff --git a/config/help_test.go b/config/help_test.go index 31e139ba..876ad073 100644 --- a/config/help_test.go +++ b/config/help_test.go @@ -22,6 +22,8 @@ import ( "sync" "testing" + "gopkg.in/yaml.v3" + dbtype "github.com/release-argus/Argus/db/types" "github.com/release-argus/Argus/service" deployedver "github.com/release-argus/Argus/service/deployed_version" @@ -29,14 +31,12 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { - log := util.NewJLog("DEBUG", true) - log.Testing = true - LogInit(log) + logutil.Init("DEBUG", true) + logutil.Log.Testing = true os.Exit(m.Run()) } @@ -88,10 +88,10 @@ func testLoad(file string, t *testing.T) *Config { config := &Config{} flags := make(map[string]bool) - log := util.NewJLog("WARN", true) + logutil.Init("WARN", true) loadMutex.Lock() defer loadMutex.Unlock() - config.Load(file, &flags, log) + config.Load(file, &flags) t.Cleanup(func() { os.Remove(config.Settings.DataDatabaseFile()) }) return config @@ -104,16 +104,16 @@ func testLoadBasic(file string, t *testing.T) *Config { //#nosec G304 -- Loading the test config file data, err := os.ReadFile(file) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("Error reading %q\n%s", file, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) err = yaml.Unmarshal(data, config) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("Unmarshal of %q failed\n%s", file, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) saveChannel := make(chan bool, 32) config.SaveChannel = &saveChannel @@ -124,7 +124,7 @@ func testLoadBasic(file string, t *testing.T) *Config { config.HardDefaults.Service.Status.DatabaseChannel = config.DatabaseChannel config.GetOrder(data) - config.Init(false) // Log already set in TestMain + config.Init() config.CheckValues() t.Log("Loaded", file) diff --git a/config/init.go b/config/init.go index 80d1d1cd..72acfdda 100644 --- a/config/init.go +++ b/config/init.go @@ -19,26 +19,18 @@ import ( "fmt" "os" + "gopkg.in/yaml.v3" + dbtype "github.com/release-argus/Argus/db/types" "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/service/latest_version/types/github" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) -// LogInit for Argus. -func LogInit(log *util.JLog) { - if jLog != nil { - return - } - - jLog = log - service.LogInit(jLog) -} - // Init will hand out the appropriate Defaults.X and HardDefaults.X pointer(s). -func (c *Config) Init(setLog bool) { +func (c *Config) Init() { c.OrderMutex.RLock() defer c.OrderMutex.RUnlock() @@ -57,17 +49,14 @@ func (c *Config) Init(setLog bool) { c.HardDefaults.Service.Status.SaveChannel = c.SaveChannel - if setLog { - jLog.SetTimestamps(*c.Settings.LogTimestamps()) - jLog.SetLevel(c.Settings.LogLevel()) - } + logutil.Init(c.Settings.LogLevel(), *c.Settings.LogTimestamps()) for i, name := range c.Order { service := c.Service[name] - jLog.Debug( + logutil.Log.Debug( fmt.Sprintf("%d/%d %s Init", i+1, len(c.Service), service.Name), - util.LogFrom{}, true) + logutil.LogFrom{}, true) service.Init( &c.Defaults.Service, &c.HardDefaults.Service, &c.Notify, &c.Defaults.Notify, &c.HardDefaults.Notify, @@ -76,26 +65,23 @@ func (c *Config) Init(setLog bool) { } // Load `file` as Config. -func (c *Config) Load(file string, flagset *map[string]bool, log *util.JLog) { +func (c *Config) Load(file string, flagset *map[string]bool) { c.File = file // Give the log to the other packages. - if log != nil { - LogInit(log) - } c.Settings.NilUndefinedFlags(flagset) //#nosec G304 -- Loading the file asked for by the user. data, err := os.ReadFile(file) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("Error reading %q\n%s", file, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) err = yaml.Unmarshal(data, c) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("Unmarshal of %q failed\n%s", file, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) c.GetOrder(data) @@ -127,6 +113,6 @@ func (c *Config) Load(file string, flagset *map[string]bool, log *util.JLog) { // SaveHandler that listens for calls to save config changes. go c.SaveHandler() - c.Init(log != nil) + c.Init() c.CheckValues() } diff --git a/config/init_test.go b/config/init_test.go index 57f6f6e1..437395df 100644 --- a/config/init_test.go +++ b/config/init_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ package config import ( "testing" - - "github.com/release-argus/Argus/util" ) func TestConfig_Load(t *testing.T) { @@ -69,7 +67,7 @@ func TestConfig_LoadDeleteNil(t *testing.T) { configFile(file, t) // WHEN Load is called on it - config.Load(file, &flags, &util.JLog{}) + config.Load(file, &flags) // THEN Services that are nil are deleted for name, service := range config.Service { @@ -95,7 +93,7 @@ func TestConfig_LoadDefaults(t *testing.T) { configFile(file, t) // WHEN Load is called on it - config.Load(file, &flags, &util.JLog{}) + config.Load(file, &flags) // THEN the defaults are assigned correctly to Services want := false diff --git a/config/ordering.go b/config/ordering.go index 032e7a3c..4dbc2b5d 100644 --- a/config/ordering.go +++ b/config/ordering.go @@ -21,8 +21,9 @@ import ( "regexp" "strings" - "github.com/release-argus/Argus/util" "gopkg.in/yaml.v3" + + "github.com/release-argus/Argus/util" ) // GetOrder of the Services from `c.File`. diff --git a/config/ordering_test.go b/config/ordering_test.go index b17087c6..d6132ec0 100644 --- a/config/ordering_test.go +++ b/config/ordering_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -76,7 +76,7 @@ func TestConfig_LoadOrdering(t *testing.T) { flags := make(map[string]bool) var config Config loadMutex.Lock() // Protect flag env vars - config.Load(file, &flags, nil) + config.Load(file, &flags) t.Cleanup(func() { os.Remove(config.Settings.DataDatabaseFile()) loadMutex.Unlock() diff --git a/config/save.go b/config/save.go index cab85e39..2430517e 100644 --- a/config/save.go +++ b/config/save.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,9 +22,11 @@ import ( "strings" "time" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) // SaveHandler will listen to the `SaveChannel` and save the config (after a delay) @@ -65,10 +67,10 @@ func (c *Config) Save() { // Write the config to file (unordered slices, but with an order list). file, err := os.OpenFile(c.File, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0_600) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("error opening %s: %v", c.File, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) defer file.Close() // Create the yaml encoder and set indentation. @@ -77,23 +79,23 @@ func (c *Config) Save() { // Write and close the file. err = yamlEncoder.Encode(c) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("error encoding %s:\n%v\n", c.File, err), - util.LogFrom{}, + logutil.LogFrom{}, err != nil) err = file.Close() - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("error closing %s:\n%v\n", c.File, err), - util.LogFrom{}, + logutil.LogFrom{}, err != nil) // Read the file to find what needs to be re-arranged. data, err := os.ReadFile(c.File) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("Error reading %q\n%s", c.File, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) lines := strings.Split(string(util.NormaliseNewlines(data)), "\n") // Fix the ordering of the read data. @@ -257,10 +259,10 @@ func (c *Config) Save() { // Open the file. file, err = os.OpenFile(c.File, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0_600) - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("error opening %s after initial save: %v", c.File, err), - util.LogFrom{}, err != nil) + logutil.LogFrom{}, err != nil) // Buffered writes to the file. writer := bufio.NewWriter(file) @@ -271,13 +273,13 @@ func (c *Config) Save() { // Flush the writes. err = writer.Flush() - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("error writing %s after initial save: %v", c.File, err), - util.LogFrom{}, err != nil) - jLog.Info( + logutil.LogFrom{}, err != nil) + logutil.Log.Info( fmt.Sprintf("Saved service updates to %s", c.File), - util.LogFrom{}, true) + logutil.LogFrom{}, true) } // removeAllServiceDefaults removes the written default values from all Services. diff --git a/config/settings.go b/config/settings.go index f28f1800..558ca599 100644 --- a/config/settings.go +++ b/config/settings.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( "strings" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Export the flags. @@ -76,9 +77,9 @@ func (s *SettingsBase) CheckValues() { func (s *SettingsBase) MapEnvToStruct() { err := mapEnvToStruct(s, "", nil) if err != nil { - jLog.Fatal( + logutil.Log.Fatal( "One or more 'ARGUS_' environment variables are incorrect:\n"+err.Error(), - util.LogFrom{}, true) + logutil.LogFrom{}, true) } s.CheckValues() // Set hash values and remove empty structs. } @@ -323,7 +324,7 @@ func (s *Settings) WebCertFile() string { if _, err := os.Stat(certFile); err != nil { if !filepath.IsAbs(certFile) { path, execErr := os.Executable() - jLog.Error(execErr, util.LogFrom{}, execErr != nil) + logutil.Log.Error(execErr, logutil.LogFrom{}, execErr != nil) // Add the path to the error message. err = errors.New(strings.Replace( err.Error(), @@ -332,7 +333,7 @@ func (s *Settings) WebCertFile() string { 1, )) } - jLog.Fatal("settings.web.cert_file "+err.Error(), util.LogFrom{}, true) + logutil.Log.Fatal("settings.web.cert_file "+err.Error(), logutil.LogFrom{}, true) } return certFile } @@ -349,7 +350,7 @@ func (s *Settings) WebKeyFile() string { if _, err := os.Stat(keyFile); err != nil { if !filepath.IsAbs(keyFile) { path, execErr := os.Executable() - jLog.Error(execErr, util.LogFrom{}, execErr != nil) + logutil.Log.Error(execErr, logutil.LogFrom{}, execErr != nil) // Add the path to the error message. err = errors.New(strings.Replace( err.Error(), @@ -358,7 +359,7 @@ func (s *Settings) WebKeyFile() string { 1, )) } - jLog.Fatal("settings.web.key_file "+err.Error(), util.LogFrom{}, true) + logutil.Log.Fatal("settings.web.key_file "+err.Error(), logutil.LogFrom{}, true) } return keyFile } diff --git a/config/types.go b/config/types.go index d07b6518..3658ef63 100644 --- a/config/types.go +++ b/config/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,14 +21,9 @@ import ( dbtype "github.com/release-argus/Argus/db/types" "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service" - "github.com/release-argus/Argus/util" "github.com/release-argus/Argus/webhook" ) -var ( - jLog *util.JLog -) - // Config for Argus. type Config struct { File string `yaml:"-"` // Path to the config file (--config.file=''). diff --git a/config/verify.go b/config/verify.go index 469b0ad7..fce1ca14 100644 --- a/config/verify.go +++ b/config/verify.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import ( "os" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // CheckValues validates the fields of the Config struct. @@ -41,7 +42,7 @@ func (c *Config) CheckValues() { if len(errs) > 0 { combinedErr := errors.Join(errs...) fmt.Println(combinedErr.Error()) - jLog.Fatal("Config could not be parsed successfully.", util.LogFrom{}, true) + logutil.Log.Fatal("Config could not be parsed successfully.", logutil.LogFrom{}, true) } } @@ -64,7 +65,7 @@ func (c *Config) Print(flag *bool) { c.Service.Print("", c.Order) fmt.Println() } - if !jLog.Testing { + if !logutil.Log.Testing { os.Exit(0) } } diff --git a/db/handlers.go b/db/handlers.go index 6190a16a..e4f6465a 100644 --- a/db/handlers.go +++ b/db/handlers.go @@ -20,6 +20,7 @@ import ( "strings" dbtype "github.com/release-argus/Argus/db/types" + logutil "github.com/release-argus/Argus/util/log" ) // handler will listen to the DatabaseChannel and act on @@ -74,15 +75,15 @@ func (api *api) updateRow(serviceID string, cells []dbtype.Cell) { params[i] = cells[i].Value } - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("%s, %v", sqlStmt, params), logFrom, true) } res, err := api.db.Exec(sqlStmt, params...) // Query failed. if err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("updateRow UPDATE: %q %v, %s", sqlStmt, params, err), logFrom, true) @@ -118,15 +119,15 @@ func (api *api) updateRow(serviceID string, cells []dbtype.Cell) { sqlStmt = fmt.Sprintf("INSERT INTO status (%s,`id`) VALUES (?,%s)", columnsBuilder.String(), valuesPlaceholderBuilder.String()) // Log the SQL statement. - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("%s, %v", sqlStmt, params), logFrom, true) } // Execute and log any errors. if _, err := api.db.Exec(sqlStmt, params...); err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("updateRow INSERT: %q %v, %s", sqlStmt, params, err), logFrom, true) @@ -138,15 +139,15 @@ func (api *api) deleteRow(serviceID string) { // The SQL statement. sqlStmt := "DELETE FROM status WHERE id = ?" // Log the SQL statement. - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("%s, %v", sqlStmt, serviceID), logFrom, true) } // Execute and log any errors. if _, err := api.db.Exec(sqlStmt, serviceID); err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("deleteRow: %q with %q, %s", sqlStmt, serviceID, err), logFrom, true) diff --git a/db/help_test.go b/db/help_test.go index 4af36bf7..63457a2d 100644 --- a/db/help_test.go +++ b/db/help_test.go @@ -29,7 +29,7 @@ import ( "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) var cfg *config.Config @@ -38,13 +38,12 @@ func TestMain(m *testing.M) { databaseFile := "TestDB.db" // Log. - jLog := util.NewJLog("DEBUG", false) - jLog.Testing = true - LogInit(jLog, databaseFile) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true cfg = testConfig() cfg.Settings.Data.DatabaseFile = databaseFile - Run(cfg, nil) + Run(cfg) exitCode := m.Run() os.Remove(cfg.Settings.Data.DatabaseFile) diff --git a/db/init.go b/db/init.go index b61a3a8e..00b4cdc5 100644 --- a/db/init.go +++ b/db/init.go @@ -21,20 +21,12 @@ import ( "os" "path/filepath" "strings" + "sync" "github.com/release-argus/Argus/config" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) -// LogInit for this package. -func LogInit(log *util.JLog, databaseFile string) { - // Only set the log if it has not been set (avoid RACE condition). - if jLog == nil { - jLog = log - logFrom = util.LogFrom{Primary: "db", Secondary: databaseFile} - } -} - func checkFile(path string) { file := filepath.Base(path) // Check the directory exists. @@ -45,16 +37,16 @@ func checkFile(path string) { if os.IsNotExist(err) { // Create the dir. if err := os.MkdirAll(dir, 0_750); err != nil { - jLog.Fatal(err, logFrom, true) + logutil.Log.Fatal(err, logFrom, true) } } else { // other error. - jLog.Fatal(err, logFrom, true) + logutil.Log.Fatal(err, logFrom, true) } // Directory exists, but is not a directory. } else if fileInfo == nil || !fileInfo.IsDir() { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("path %q (for %q) is not a directory", dir, file), logFrom, true) @@ -64,22 +56,27 @@ func checkFile(path string) { fileInfo, err = os.Stat(path) if err != nil { // File doesn't exist. - jLog.Fatal(err, logFrom, os.IsExist(err)) + logutil.Log.Fatal(err, logFrom, os.IsExist(err)) // Item exists, but is a directory. } else if fileInfo != nil && fileInfo.IsDir() { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("path %q (for %q) is a directory, not a file", path, file), logFrom, true) } } +var once sync.Once + // Run will start the database, initialise it and run the handler for messages in the background. -func Run(cfg *config.Config, log *util.JLog) { - if log != nil { - LogInit(log, cfg.Settings.DataDatabaseFile()) - } +func Run(cfg *config.Config) { + once.Do(func() { + if logFrom.Secondary == "" { + logFrom.Secondary = cfg.Settings.DataDatabaseFile() + } + }) + api := api{config: cfg} api.initialise() @@ -103,7 +100,7 @@ func (api *api) initialise() { databaseFile := api.config.Settings.DataDatabaseFile() checkFile(databaseFile) db, err := sql.Open("sqlite", databaseFile) - jLog.Fatal(err, logFrom, err != nil) + logutil.Log.Fatal(err, logFrom, err != nil) // Create the table. sqlStmt := ` @@ -116,7 +113,7 @@ func (api *api) initialise() { approved_version TEXT DEFAULT '' );` if _, err := db.Exec(sqlStmt); err != nil { - jLog.Fatal(err, logFrom, true) + logutil.Log.Fatal(err, logFrom, true) } updateTable(db) @@ -144,7 +141,7 @@ func (api *api) removeUnknownServices() { } if _, err := api.db.Exec(sqlStmt, params...); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("removeUnknownServices: %s", err), logFrom, true) @@ -163,7 +160,7 @@ func (api *api) extractServiceStatus() { deployed_version_timestamp, approved_version FROM status;`) - jLog.Fatal(err, logFrom, err != nil) + logutil.Log.Fatal(err, logFrom, err != nil) defer rows.Close() api.config.OrderMutex.RLock() @@ -178,7 +175,7 @@ func (api *api) extractServiceStatus() { av string ) if err := rows.Scan(&id, &lv, &lvt, &dv, &dvt, &av); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("extractServiceStatus row: %s", err), logFrom, true) @@ -188,7 +185,7 @@ func (api *api) extractServiceStatus() { api.config.Service[id].Status.SetApprovedVersion(av, false) } if err := rows.Err(); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("extractServiceStatus: %s", err), logFrom, true) @@ -200,16 +197,16 @@ func updateTable(db *sql.DB) { // Get the type of the *_version columns. var columnType string if err := db.QueryRow("SELECT type FROM pragma_table_info('status') WHERE name = 'latest_version'").Scan(&columnType); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("updateTable: %s", err), logFrom, true) } // Update if the column type is not TEXT. if columnType != "TEXT" { - jLog.Verbose("Updating column types", logFrom, true) + logutil.Log.Verbose("Updating column types", logFrom, true) updateColumnTypes(db) - jLog.Verbose("Finished updating column types", logFrom, true) + logutil.Log.Verbose("Finished updating column types", logFrom, true) } } @@ -226,14 +223,14 @@ func updateColumnTypes(db *sql.DB) { approved_version TEXT DEFAULT '' );` if _, err := db.Exec(sqlStmt); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("updateColumnTypes - create: %s", err), logFrom, true) } // Copy the data from the old table to the new table. if _, err := db.Exec(`INSERT INTO status_backup SELECT * FROM status;`); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("updateColumnTypes - copy: %s", err), logFrom, true) @@ -241,7 +238,7 @@ func updateColumnTypes(db *sql.DB) { // Drop the table. if _, err := db.Exec("DROP TABLE status;"); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("updateColumnTypes - drop: %s", err), logFrom, true) @@ -249,7 +246,7 @@ func updateColumnTypes(db *sql.DB) { // Rename the new table to the old table. if _, err := db.Exec("ALTER TABLE status_backup RENAME TO status;"); err != nil { - jLog.Fatal( + logutil.Log.Fatal( fmt.Sprintf("updateColumnTypes - rename: %s", err), logFrom, true) diff --git a/db/types.go b/db/types.go index e0a13ef6..9e061f00 100644 --- a/db/types.go +++ b/db/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import ( "database/sql" "github.com/release-argus/Argus/config" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) type api struct { @@ -28,6 +28,5 @@ type api struct { } var ( - jLog *util.JLog - logFrom util.LogFrom + logFrom logutil.LogFrom = logutil.LogFrom{Primary: "db"} ) diff --git a/notify/shoutrrr/help_test.go b/notify/shoutrrr/help_test.go index 2c627950..d76f715d 100644 --- a/notify/shoutrrr/help_test.go +++ b/notify/shoutrrr/help_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,14 +23,13 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - LogInit(jLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/notify/shoutrrr/init.go b/notify/shoutrrr/init.go index 0004e6da..0d779343 100644 --- a/notify/shoutrrr/init.go +++ b/notify/shoutrrr/init.go @@ -21,11 +21,6 @@ import ( "github.com/release-argus/Argus/web/metric" ) -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} - // Init the Slice metrics amd hand out the defaults. func (s *Slice) Init( serviceStatus *status.Status, diff --git a/notify/shoutrrr/shoutrrr.go b/notify/shoutrrr/shoutrrr.go index 202d6025..5baf8019 100644 --- a/notify/shoutrrr/shoutrrr.go +++ b/notify/shoutrrr/shoutrrr.go @@ -24,10 +24,12 @@ import ( "strings" "time" - shoutrrr_lib "github.com/containrrr/shoutrrr" + "github.com/containrrr/shoutrrr" "github.com/containrrr/shoutrrr/pkg/router" "github.com/containrrr/shoutrrr/pkg/types" + "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web/metric" ) @@ -76,12 +78,12 @@ func (s *Shoutrrr) Send( useDelay bool, useMetrics bool, ) error { - logFrom := util.LogFrom{Primary: s.ID, Secondary: serviceInfo.ID} // For logging. + logFrom := logutil.LogFrom{Primary: s.ID, Secondary: serviceInfo.ID} // For logging. if useDelay && s.GetDelay() != "0s" { // Delay sending the Shoutrrr message by the defined interval. msg := fmt.Sprintf("%s, Sleeping for %s before sending the Shoutrrr message", s.ID, s.GetDelay()) - jLog.Info(msg, logFrom, s.GetDelay() != "0s") + logutil.Log.Info(msg, logFrom, s.GetDelay() != "0s") time.Sleep(s.GetDelayDuration()) } @@ -91,10 +93,10 @@ func (s *Shoutrrr) Send( } // Try sending the message. - if jLog.IsLevel("VERBOSE") || jLog.IsLevel("DEBUG") { + if logutil.Log.IsLevel("VERBOSE") || logutil.Log.IsLevel("DEBUG") { msg := fmt.Sprintf("Sending %q to %q", message, url) - jLog.Verbose(msg, logFrom, !jLog.IsLevel("DEBUG")) - jLog.Debug( + logutil.Log.Verbose(msg, logFrom, !logutil.Log.IsLevel("DEBUG")) + logutil.Log.Debug( fmt.Sprintf("%s with params=%q", msg, *params), logFrom, true) } @@ -119,7 +121,7 @@ func (s *Shoutrrr) getSender( url := s.BuildURL() // Check the URL provides a valid sender. - sender, err := shoutrrr_lib.CreateSender(url) + sender, err := shoutrrr.CreateSender(url) if err != nil { err = fmt.Errorf("failed to create Shoutrrr sender: %w", err) return nil, "", nil, "", err @@ -438,7 +440,7 @@ func (s *Shoutrrr) send( message string, params *types.Params, serviceName string, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) error { combinedErrs := make(map[string]int) @@ -460,7 +462,7 @@ func (s *Shoutrrr) send( msg := fmt.Sprintf("failed %d times to send a %s message for %q to %q", s.GetMaxTries(), s.GetType(), *s.ServiceStatus.ServiceID, s.BuildURL()) - jLog.Error(msg, logFrom, true) + logutil.Log.Error(msg, logFrom, true) failed := true s.Failed.Set(s.ID, &failed) errs := make([]error, 0, len(combinedErrs)) @@ -479,7 +481,7 @@ func (s *Shoutrrr) parseSend( err []error, combinedErrs map[string]int, serviceName string, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) (failed bool) { if s.ServiceStatus.Deleting() { return @@ -488,7 +490,7 @@ func (s *Shoutrrr) parseSend( for i := range err { if err[i] != nil { failed = true - jLog.Error(err[i], logFrom, true) + logutil.Log.Error(err[i], logFrom, true) combinedErrs[err[i].Error()]++ } } diff --git a/notify/shoutrrr/shoutrrr_integration_test.go b/notify/shoutrrr/shoutrrr_integration_test.go index 4b037fc8..75184ea9 100644 --- a/notify/shoutrrr/shoutrrr_integration_test.go +++ b/notify/shoutrrr/shoutrrr_integration_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" metric "github.com/release-argus/Argus/web/metric" diff --git a/notify/shoutrrr/shoutrrr_test.go b/notify/shoutrrr/shoutrrr_test.go index b9c33139..4feb952f 100644 --- a/notify/shoutrrr/shoutrrr_test.go +++ b/notify/shoutrrr/shoutrrr_test.go @@ -22,10 +22,12 @@ import ( "reflect" "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) func TestShoutrrr_getSender(t *testing.T) { @@ -781,7 +783,7 @@ func TestShoutrrr_parseSend(t *testing.T) { if tc.deleting { shoutrrr.ServiceStatus.SetDeleting() } - logFrom := util.LogFrom{Primary: "test", Secondary: "test"} + logFrom := logutil.LogFrom{Primary: "test", Secondary: "test"} combinedErrs := map[string]int{} failed := shoutrrr.parseSend(tc.errs, combinedErrs, tc.serviceName, logFrom) diff --git a/notify/shoutrrr/types.go b/notify/shoutrrr/types.go index f745243d..85d92dfc 100644 --- a/notify/shoutrrr/types.go +++ b/notify/shoutrrr/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import ( ) var ( - jLog *util.JLog supportedTypes = []string{ "bark", "discord", "smtp", "gotify", "googlechat", "ifttt", "join", "mattermost", "matrix", "ntfy", "opsgenie", "pushbullet", "pushover", "rocketchat", "slack", "teams", "telegram", "zulip", "generic", "shoutrrr"} diff --git a/service/dashboard.go b/service/dashboard.go index 963cd684..bb86e567 100644 --- a/service/dashboard.go +++ b/service/dashboard.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,8 +20,9 @@ import ( "errors" "fmt" - "github.com/release-argus/Argus/util" "gopkg.in/yaml.v3" + + "github.com/release-argus/Argus/util" ) // DashboardOptionsBase are the base options for the Dashboard. diff --git a/service/dashboard_test.go b/service/dashboard_test.go index 611b15f2..2762b55d 100644 --- a/service/dashboard_test.go +++ b/service/dashboard_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,9 +20,10 @@ import ( "strings" "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) func TestNewDashboardOptions(t *testing.T) { diff --git a/service/deployed_version/help_test.go b/service/deployed_version/help_test.go index 8e12bc1d..ca0b8bae 100644 --- a/service/deployed_version/help_test.go +++ b/service/deployed_version/help_test.go @@ -24,14 +24,13 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - mainJLog := util.NewJLog("DEBUG", false) - mainJLog.Testing = true - LogInit(mainJLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/service/deployed_version/init.go b/service/deployed_version/init.go index c74bb708..6ccb695e 100644 --- a/service/deployed_version/init.go +++ b/service/deployed_version/init.go @@ -18,15 +18,9 @@ package deployedver import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" - "github.com/release-argus/Argus/util" "github.com/release-argus/Argus/web/metric" ) -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} - // Init will initialise the Service metric. func (l *Lookup) Init( options *opt.Options, diff --git a/service/deployed_version/init_test.go b/service/deployed_version/init_test.go index 996331e0..1b2d02af 100644 --- a/service/deployed_version/init_test.go +++ b/service/deployed_version/init_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/prometheus/client_golang/prometheus/testutil" + opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" diff --git a/service/deployed_version/query.go b/service/deployed_version/query.go index 05c1758f..ebb9964e 100644 --- a/service/deployed_version/query.go +++ b/service/deployed_version/query.go @@ -25,7 +25,9 @@ import ( "time" "github.com/Masterminds/semver/v3" + "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web/metric" ) @@ -34,7 +36,7 @@ func (l *Lookup) Track() { if l == nil { return } - logFrom := util.LogFrom{Primary: *l.Status.ServiceID} + logFrom := logutil.LogFrom{Primary: *l.Status.ServiceID} // Track forever. for { @@ -53,7 +55,7 @@ func (l *Lookup) Track() { } // query the deployed version (DeployedVersion) of the Service. -func (l *Lookup) query(logFrom util.LogFrom) (string, error) { +func (l *Lookup) query(logFrom logutil.LogFrom) (string, error) { body, err := l.httpRequest(logFrom) if err != nil { return "", err @@ -64,7 +66,7 @@ func (l *Lookup) query(logFrom util.LogFrom) (string, error) { if l.JSON != "" { version, err = util.GetValueByKey(body, l.JSON, l.GetURL()) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) //nolint:wrapcheck return "", err } @@ -81,7 +83,7 @@ func (l *Lookup) query(logFrom util.LogFrom) (string, error) { if len(texts) == 0 { err := fmt.Errorf("regex %q didn't return any matches on %q", l.Regex, util.TruncateMessage(version, 100)) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return "", err } @@ -98,7 +100,7 @@ func (l *Lookup) query(logFrom util.LogFrom) (string, error) { "style of 'MAJOR.MINOR.PATCH' (https://semver.org/), or disabling semantic versioning "+ "(globally with defaults.service.semantic_versioning or just for this service with the semantic_versioning var)", version) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return "", err } } @@ -107,7 +109,7 @@ func (l *Lookup) query(logFrom util.LogFrom) (string, error) { } // Query the deployed version (DeployedVersion) of the Service. -func (l *Lookup) Query(metrics bool, logFrom util.LogFrom) (string, error) { +func (l *Lookup) Query(metrics bool, logFrom logutil.LogFrom) (string, error) { version, err := l.query(logFrom) if metrics { @@ -172,15 +174,15 @@ func (l *Lookup) HandleNewVersion(version string, writeToDB bool) { } // Announce version change to WebSocket clients. - jLog.Info( + logutil.Log.Info( fmt.Sprintf("Updated to %q", version), - util.LogFrom{Primary: *l.Status.ServiceID}, + logutil.LogFrom{Primary: *l.Status.ServiceID}, true) l.Status.AnnounceUpdate() } // httpRequest sends an HTTP request to the URL and returns the response body. -func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) httpRequest(logFrom logutil.LogFrom) ([]byte, error) { // HTTPS insecure skip verify. customTransport := &http.Transport{} if l.GetAllowInvalidCerts() { @@ -192,7 +194,7 @@ func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { // Create the request. req, err := http.NewRequest(l.Method, l.GetURL(), l.GetBody()) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err //nolint:wrapcheck } // Set headers. @@ -212,23 +214,23 @@ func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { // Don't crash on invalid certs. if strings.Contains(err.Error(), "x509") { err = fmt.Errorf("x509 (certificate invalid)") - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return nil, err } - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } // Ignore non-2XX responses. if resp.StatusCode < 200 || resp.StatusCode >= 300 { err = fmt.Errorf("non-2XX response code: %d", resp.StatusCode) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return nil, err } // Read the response body. defer resp.Body.Close() body, err := io.ReadAll(resp.Body) - jLog.Error(err, logFrom, err != nil) + logutil.Log.Error(err, logFrom, err != nil) return body, err //nolint:wrapcheck } diff --git a/service/deployed_version/query_test.go b/service/deployed_version/query_test.go index 5efbd6d3..99ba8f04 100644 --- a/service/deployed_version/query_test.go +++ b/service/deployed_version/query_test.go @@ -22,13 +22,15 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/testutil" + "gopkg.in/yaml.v3" + dbtype "github.com/release-argus/Argus/db/types" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" metric "github.com/release-argus/Argus/web/metric" - "gopkg.in/yaml.v3" ) func TestLookup_HTTPRequest(t *testing.T) { @@ -72,7 +74,7 @@ func TestLookup_HTTPRequest(t *testing.T) { lookup.URL = tc.url // WHEN httpRequest is called on it. - _, err := lookup.httpRequest(util.LogFrom{}) + _, err := lookup.httpRequest(logutil.LogFrom{}) // THEN any err is expected. e := util.ErrorToString(err) @@ -264,7 +266,7 @@ func TestLookup_Query(t *testing.T) { } // WHEN Query is called on it. - version, err := dvl.Query(true, util.LogFrom{}) + version, err := dvl.Query(true, logutil.LogFrom{}) // THEN any err is expected. if tc.wantVersion != "" { diff --git a/service/deployed_version/refresh.go b/service/deployed_version/refresh.go index 1412475d..0c6c61b6 100644 --- a/service/deployed_version/refresh.go +++ b/service/deployed_version/refresh.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Refresh creates a new Lookup instance (if overrides are provided), and queries the Lookup for the deployed version @@ -33,7 +34,7 @@ func (l *Lookup) Refresh( if l == nil { return "", fmt.Errorf("lookup is nil") } - logFrom := util.LogFrom{Primary: "deployed_version/refresh", Secondary: *serviceID} + logFrom := logutil.LogFrom{Primary: "deployed_version/refresh", Secondary: *serviceID} // Whether this new semantic_version resolves differently than the current one. semanticVerDiff := semanticVersioning != nil && ( @@ -61,8 +62,8 @@ func (l *Lookup) Refresh( } // Log the lookup in use. - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("Refreshing with:\n%q", lookup.String("")), logFrom, true) } diff --git a/service/deployed_version/refresh_test.go b/service/deployed_version/refresh_test.go index 598b12b8..84a7a08a 100644 --- a/service/deployed_version/refresh_test.go +++ b/service/deployed_version/refresh_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,11 +23,12 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestLookup_Refresh(t *testing.T) { testL := testLookup() - testVersion, _ := testL.Query(true, util.LogFrom{Primary: "TestLookup_Refresh"}) + testVersion, _ := testL.Query(true, logutil.LogFrom{Primary: "TestLookup_Refresh"}) if testVersion == "" { t.Fatalf("test version is empty") } diff --git a/service/deployed_version/types.go b/service/deployed_version/types.go index e9851b56..8cab7152 100644 --- a/service/deployed_version/types.go +++ b/service/deployed_version/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import ( ) var ( - jLog *util.JLog supportedTypes = []string{"GET", "POST"} ) diff --git a/service/handlers.go b/service/handlers.go index 80ef5bb8..bd87020f 100644 --- a/service/handlers.go +++ b/service/handlers.go @@ -21,6 +21,7 @@ import ( "time" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -37,7 +38,7 @@ func (s *Service) HandleCommand(command string) { // Find the command. index, err := s.CommandController.Find(command) if err != nil { - jLog.Warn(err, util.LogFrom{Primary: "Command", Secondary: s.ID}, true) + logutil.Log.Warn(err, logutil.LogFrom{Primary: "Command", Secondary: s.ID}, true) return } @@ -47,7 +48,7 @@ func (s *Service) HandleCommand(command string) { } // Send the Command. - err = (*s.CommandController).ExecIndex(util.LogFrom{Primary: "Command", Secondary: s.ID}, index) + err = (*s.CommandController).ExecIndex(logutil.LogFrom{Primary: "Command", Secondary: s.ID}, index) if err == nil { s.UpdatedVersion(true) } @@ -87,11 +88,11 @@ func (s *Service) HandleUpdateActions(writeToDB bool) { if s.Dashboard.GetAutoApprove() { msg := fmt.Sprintf("Sending WebHooks/Running Commands for %q", s.Status.LatestVersion()) - jLog.Info(msg, util.LogFrom{Primary: s.ID}, true) + logutil.Log.Info(msg, logutil.LogFrom{Primary: s.ID}, true) // Run the Command(s). go func() { - err := s.CommandController.Exec(util.LogFrom{Primary: "Command", Secondary: s.ID}) + err := s.CommandController.Exec(logutil.LogFrom{Primary: "Command", Secondary: s.ID}) if err == nil && len(s.Command) != 0 { s.UpdatedVersion(writeToDB) } @@ -105,7 +106,7 @@ func (s *Service) HandleUpdateActions(writeToDB bool) { } }() } else { - jLog.Info("Waiting for approval on the Web UI", util.LogFrom{Primary: s.ID}, true) + logutil.Log.Info("Waiting for approval on the Web UI", logutil.LogFrom{Primary: s.ID}, true) s.Status.AnnounceQueryNewVersion() } @@ -151,7 +152,7 @@ func (s *Service) HandleFailedActions() { // Run the Command(s). if len(s.Command) != 0 { potentialErrors += len(s.Command) - logFrom := util.LogFrom{Primary: "Command", Secondary: s.ID} + logFrom := logutil.LogFrom{Primary: "Command", Secondary: s.ID} for key := range s.Command { if retryAll || util.DereferenceOrNilValue(s.Status.Fails.Command.Get(key), true) { // Skip if before NextRunnable. diff --git a/service/help_test.go b/service/help_test.go index 5d7a06a8..6ceca77b 100644 --- a/service/help_test.go +++ b/service/help_test.go @@ -28,14 +28,13 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - LogInit(jLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/service/init.go b/service/init.go index 24e6160f..9202255d 100644 --- a/service/init.go +++ b/service/init.go @@ -20,20 +20,11 @@ import ( "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/notify/shoutrrr" - deployedver "github.com/release-argus/Argus/service/deployed_version" - latestver "github.com/release-argus/Argus/service/latest_version" "github.com/release-argus/Argus/util" "github.com/release-argus/Argus/web/metric" "github.com/release-argus/Argus/webhook" ) -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log - deployedver.LogInit(log) - latestver.LogInit(log) -} - // ServiceInfo returns info about the service. func (s *Service) ServiceInfo() util.ServiceInfo { return util.ServiceInfo{ diff --git a/service/init_test.go b/service/init_test.go index ed9e15ba..5f5c50cd 100644 --- a/service/init_test.go +++ b/service/init_test.go @@ -22,6 +22,8 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/testutil" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/notify/shoutrrr" shoutrrr_test "github.com/release-argus/Argus/notify/shoutrrr/test" @@ -31,7 +33,6 @@ import ( metric "github.com/release-argus/Argus/web/metric" "github.com/release-argus/Argus/webhook" webhook_test "github.com/release-argus/Argus/webhook/test" - "gopkg.in/yaml.v3" ) func TestService_ServiceInfo(t *testing.T) { diff --git a/service/latest_version/filter/command.go b/service/latest_version/filter/command.go index 6cb0569e..e6d53495 100644 --- a/service/latest_version/filter/command.go +++ b/service/latest_version/filter/command.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,11 +18,11 @@ package filter import ( "fmt" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // ExecCommand will run Command. -func (r *Require) ExecCommand(logFrom util.LogFrom) error { +func (r *Require) ExecCommand(logFrom logutil.LogFrom) error { if r == nil || len(r.Command) == 0 { return nil } diff --git a/service/latest_version/filter/command_test.go b/service/latest_version/filter/command_test.go index 9a61219b..87e0e648 100644 --- a/service/latest_version/filter/command_test.go +++ b/service/latest_version/filter/command_test.go @@ -23,6 +23,7 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestRequire_ExecCommand(t *testing.T) { @@ -55,7 +56,7 @@ func TestRequire_ExecCommand(t *testing.T) { test.StringPtr("http://example.com")) // WHEN ApplyTemplate is called on the Command - err := require.ExecCommand(util.LogFrom{}) + err := require.ExecCommand(logutil.LogFrom{}) // THEN the err is expected e := util.ErrorToString(err) diff --git a/service/latest_version/filter/help_test.go b/service/latest_version/filter/help_test.go index da5b0174..e7bf7b34 100644 --- a/service/latest_version/filter/help_test.go +++ b/service/latest_version/filter/help_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,14 +22,13 @@ import ( "time" "github.com/release-argus/Argus/command" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - mainJLog := util.NewJLog("DEBUG", false) - mainJLog.Testing = true - LogInit(mainJLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/service/latest_version/filter/regex.go b/service/latest_version/filter/regex.go index 8e77d9aa..9c077cfe 100644 --- a/service/latest_version/filter/regex.go +++ b/service/latest_version/filter/regex.go @@ -21,12 +21,13 @@ import ( github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // RegexCheckVersion returns whether `version` matches the regex. func (r *Require) RegexCheckVersion( version string, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) error { if r == nil { return nil @@ -41,7 +42,7 @@ func (r *Require) RegexCheckVersion( err := fmt.Errorf("regex %q not matched on version %q", r.RegexVersion, version) r.Status.RegexMissVersion() - jLog.Info(err, logFrom, r.Status.RegexMissesVersion() == 1) + logutil.Log.Info(err, logFrom, r.Status.RegexMissesVersion() == 1) return err } @@ -50,13 +51,13 @@ func (r *Require) RegexCheckVersion( func (r *Require) regexCheckString( version string, - logFrom util.LogFrom, + logFrom logutil.LogFrom, searchArea ...string, ) bool { for _, text := range searchArea { regexMatch := util.RegexCheckWithVersion(r.RegexContent, text, version) - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("%q RegexContent on %q, match=%t", r.RegexContent, text, regexMatch), logFrom, true) @@ -69,7 +70,7 @@ func (r *Require) regexCheckString( } // regexCheckContentFail simply returns an error for the RegexCheckContent* functions. -func (r *Require) regexCheckContentFail(version string, logFrom util.LogFrom) error { +func (r *Require) regexCheckContentFail(version string, logFrom logutil.LogFrom) error { // Escape all dots in the version. regexStr := util.TemplateString(r.RegexContent, util.ServiceInfo{ @@ -78,7 +79,7 @@ func (r *Require) regexCheckContentFail(version string, logFrom util.LogFrom) er err := fmt.Errorf( "regex %q not matched on content for version %q", regexStr, version) - jLog.Info(err, logFrom, r.Status.RegexMissesContent() == 1) + logutil.Log.Info(err, logFrom, r.Status.RegexMissesContent() == 1) return err } @@ -86,7 +87,7 @@ func (r *Require) regexCheckContentFail(version string, logFrom util.LogFrom) er func (r *Require) RegexCheckContent( version string, body string, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) error { if r == nil || r.RegexContent == "" { return nil @@ -108,7 +109,7 @@ func (r *Require) RegexCheckContent( func (r *Require) RegexCheckContentGitHub( version string, assets []github_types.Asset, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) (string, error) { if r == nil || r.RegexContent == "" { return "", nil diff --git a/service/latest_version/filter/regex_test.go b/service/latest_version/filter/regex_test.go index f4ae1579..0b4f8b55 100644 --- a/service/latest_version/filter/regex_test.go +++ b/service/latest_version/filter/regex_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import ( github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestRequire_RegexCheckVersion(t *testing.T) { @@ -52,7 +53,7 @@ func TestRequire_RegexCheckVersion(t *testing.T) { } // WHEN RegexCheckVersion is called on it - err := tc.require.RegexCheckVersion("0.1.1-beta", util.LogFrom{}) + err := tc.require.RegexCheckVersion("0.1.1-beta", logutil.LogFrom{}) // THEN the err is what we expect e := util.ErrorToString(err) @@ -101,7 +102,7 @@ func TestRequire_RegexCheckContent(t *testing.T) { } // WHEN RegexCheckContent is called on it - err := tc.require.RegexCheckContent("0.1.1-beta", tc.body, util.LogFrom{}) + err := tc.require.RegexCheckContent("0.1.1-beta", tc.body, logutil.LogFrom{}) // THEN the err is what we expect e := util.ErrorToString(err) @@ -158,7 +159,7 @@ func TestRequire_RegexCheckContentGitHub(t *testing.T) { } // WHEN RegexCheckContent is called on it - releaseDate, err := tc.require.RegexCheckContentGitHub("0.1.1-beta", tc.body, util.LogFrom{}) + releaseDate, err := tc.require.RegexCheckContentGitHub("0.1.1-beta", tc.body, logutil.LogFrom{}) // THEN the err is what we expect e := util.ErrorToString(err) diff --git a/service/latest_version/filter/require.go b/service/latest_version/filter/require.go index babba01e..6f19367c 100644 --- a/service/latest_version/filter/require.go +++ b/service/latest_version/filter/require.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,16 +25,6 @@ import ( "github.com/release-argus/Argus/util" ) -var ( - jLog *util.JLog -) - -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log - command.LogInit(log) -} - // RequireDefaults are the default values for the Require struct. // It contains configuration defaults for validating version requirements. type RequireDefaults struct { diff --git a/service/latest_version/filter/require_test.go b/service/latest_version/filter/require_test.go index f010d4db..1ea2e64d 100644 --- a/service/latest_version/filter/require_test.go +++ b/service/latest_version/filter/require_test.go @@ -21,11 +21,12 @@ import ( "testing" "time" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) func TestRequireDefaults_Default(t *testing.T) { diff --git a/service/latest_version/filter/urlcommand.go b/service/latest_version/filter/urlcommand.go index abbc5c1e..bc062aed 100644 --- a/service/latest_version/filter/urlcommand.go +++ b/service/latest_version/filter/urlcommand.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,8 +22,10 @@ import ( "regexp" "strings" - "github.com/release-argus/Argus/util" "gopkg.in/yaml.v3" + + "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) var urlCommandTypes = []string{"regex", "replace", "split"} @@ -119,7 +121,7 @@ func (c *URLCommand) String() string { } // GetVersions from `text` using the URLCommand(s) in this URLCommandSlice. -func (s *URLCommandSlice) GetVersions(text string, logFrom util.LogFrom) ([]string, error) { +func (s *URLCommandSlice) GetVersions(text string, logFrom logutil.LogFrom) ([]string, error) { // No URLCommands to run, so treat the text as a single version. if len(*s) == 0 { if text == "" { @@ -131,12 +133,12 @@ func (s *URLCommandSlice) GetVersions(text string, logFrom util.LogFrom) ([]stri } // Run all of the URLCommand(s) in this URLCommandSlice on `text`. -func (s *URLCommandSlice) Run(text string, logFrom util.LogFrom) ([]string, error) { +func (s *URLCommandSlice) Run(text string, logFrom logutil.LogFrom) ([]string, error) { if s == nil { return nil, nil } - urlCommandLogFrom := util.LogFrom{Primary: logFrom.Primary, Secondary: "url_commands"} + urlCommandLogFrom := logutil.LogFrom{Primary: logFrom.Primary, Secondary: "url_commands"} versions := []string{text} for _, urlCommand := range *s { if err := urlCommand.run(&versions, urlCommandLogFrom); err != nil { @@ -147,13 +149,13 @@ func (s *URLCommandSlice) Run(text string, logFrom util.LogFrom) ([]string, erro } // run this URLCommand on `text`. -func (c *URLCommand) run(versions *[]string, logFrom util.LogFrom) error { +func (c *URLCommand) run(versions *[]string, logFrom logutil.LogFrom) error { var err error for i, version := range *versions { // Iterate through the commands to filter the text. - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("Looking through:\n%q", version), logFrom, true) } @@ -177,9 +179,9 @@ func (c *URLCommand) run(versions *[]string, logFrom util.LogFrom) error { return err } - if jLog.IsLevel("DEBUG") { + if logutil.Log.IsLevel("DEBUG") { msg = fmt.Sprintf("%s\nResolved to %q", msg, version) - jLog.Debug(msg, logFrom, true) + logutil.Log.Debug(msg, logFrom, true) } } return nil @@ -191,7 +193,7 @@ func (c *URLCommand) run(versions *[]string, logFrom util.LogFrom) error { // - versionIndex: The index of the version in the `versions` slice to validate. // - versions: A pointer to the slice of version string(s) to regex. // - logFrom: Used for logging the source of the operation. -func (c *URLCommand) regex(versionIndex int, versions *[]string, logFrom util.LogFrom) error { +func (c *URLCommand) regex(versionIndex int, versions *[]string, logFrom logutil.LogFrom) error { re := regexp.MustCompile(c.Regex) version := (*versions)[versionIndex] @@ -200,7 +202,7 @@ func (c *URLCommand) regex(versionIndex int, versions *[]string, logFrom util.Lo if len(matches) == 0 { err := fmt.Errorf("%s %q didn't return any matches on %q", c.Type, c.Regex, util.TruncateMessage(version, 50)) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return err } @@ -216,7 +218,7 @@ func (c *URLCommand) regex(versionIndex int, versions *[]string, logFrom util.Lo if (len(matches) - index) < 1 { err := fmt.Errorf("%s (%s) returned %d elements on %q, but the index wants element number %d", c.Type, c.Regex, len(matches), version, index+1) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return err } @@ -247,7 +249,7 @@ func (c *URLCommand) regex(versionIndex int, versions *[]string, logFrom util.Lo // - versionIndex: The index of the version in the `versions` slice to process. // - versions: A pointer to the slice of version string(s) to modify. // - logFrom: Used for logging the source of the operation. -func (c *URLCommand) split(versionIndex int, versions *[]string, logFrom util.LogFrom) error { +func (c *URLCommand) split(versionIndex int, versions *[]string, logFrom logutil.LogFrom) error { texts, err := c.splitAllMatches((*versions)[versionIndex], logFrom) if err != nil { return err @@ -268,7 +270,7 @@ func (c *URLCommand) split(versionIndex int, versions *[]string, logFrom util.Lo if (len(texts) - index) < 1 { err := fmt.Errorf("%s (%s) returned %d elements on %q, but the index wants element number %d", c.Type, c.Text, len(texts), (*versions)[versionIndex], index+1) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return err } @@ -278,12 +280,12 @@ func (c *URLCommand) split(versionIndex int, versions *[]string, logFrom util.Lo } // splitAllMatches will split `text` on the URLCommands text, and return all matches. -func (c *URLCommand) splitAllMatches(text string, logFrom util.LogFrom) ([]string, error) { +func (c *URLCommand) splitAllMatches(text string, logFrom logutil.LogFrom) ([]string, error) { texts := strings.Split(text, c.Text) if len(texts) == 1 { err := fmt.Errorf("%s didn't find any %q to split on", c.Type, c.Text) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return nil, err } diff --git a/service/latest_version/filter/urlcommand_test.go b/service/latest_version/filter/urlcommand_test.go index 4f5d54b6..16d874f7 100644 --- a/service/latest_version/filter/urlcommand_test.go +++ b/service/latest_version/filter/urlcommand_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,24 +22,13 @@ import ( "strings" "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) -func TestLogInit(t *testing.T) { - // GIVEN a JLog - newJLog := util.NewJLog("WARN", false) - - // WHEN LogInit is called with it - LogInit(newJLog) - - // THEN the global JLog is set to its address - if jLog != newJLog { - t.Fatalf("JLog should have been initialised to the one we called Init with") - } -} - func TestURLCommandSlice_UnmarshalJSON(t *testing.T) { tests := map[string]struct { input string @@ -476,7 +465,7 @@ func TestURLCommandSlice_GetVersions(t *testing.T) { t.Parallel() // WHEN GetVersions is called on it - versions, err := tc.slice.GetVersions(tc.text, util.LogFrom{}) + versions, err := tc.slice.GetVersions(tc.text, logutil.LogFrom{}) // THEN the expected versions are returned wantVersions := strings.Join(tc.wantVersions, "__") @@ -615,7 +604,7 @@ func TestURLCommandSlice_Run(t *testing.T) { } // WHEN run is called on it - versions, err := tc.slice.Run(text, util.LogFrom{}) + versions, err := tc.slice.Run(text, logutil.LogFrom{}) // THEN the expected text was returned if !reflect.DeepEqual(tc.want, versions) { @@ -836,7 +825,7 @@ func TestURLCommand_regex(t *testing.T) { } // WHEN regex is called on it - err := tc.command.regex(tc.args.versionIndex, &tc.args.versions, util.LogFrom{}) + err := tc.command.regex(tc.args.versionIndex, &tc.args.versions, logutil.LogFrom{}) // THEN the expected versions are returned if !reflect.DeepEqual(*tc.want.versions, tc.args.versions) { @@ -951,7 +940,7 @@ func TestURLCommand_split(t *testing.T) { } // WHEN split is called on it - err := tc.command.split(tc.args.versionIndex, &tc.args.versions, util.LogFrom{}) + err := tc.command.split(tc.args.versionIndex, &tc.args.versions, logutil.LogFrom{}) // THEN the expected versions are returned if !reflect.DeepEqual(*tc.want.versions, tc.args.versions) { diff --git a/service/latest_version/help_test.go b/service/latest_version/help_test.go index 41836ede..74955fea 100644 --- a/service/latest_version/help_test.go +++ b/service/latest_version/help_test.go @@ -28,14 +28,13 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - LogInit(jLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/service/latest_version/init.go b/service/latest_version/init.go deleted file mode 100644 index 7aea3db2..00000000 --- a/service/latest_version/init.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright [2024] [Argus] -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package latestver provides the latest_version lookup service to for a service. -package latestver - -import ( - "github.com/release-argus/Argus/command" - "github.com/release-argus/Argus/notify/shoutrrr" - "github.com/release-argus/Argus/service/latest_version/filter" - "github.com/release-argus/Argus/service/latest_version/types/base" - "github.com/release-argus/Argus/service/latest_version/types/github" - "github.com/release-argus/Argus/service/latest_version/types/web" - "github.com/release-argus/Argus/util" - "github.com/release-argus/Argus/webhook" -) - -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log - - base.LogInit(log) - github.LogInit(log) - web.LogInit(log) - - filter.LogInit(log) - command.LogInit(log) - shoutrrr.LogInit(log) - webhook.LogInit(log) -} diff --git a/service/latest_version/refresh.go b/service/latest_version/refresh.go index 418955b9..4fc88fbf 100644 --- a/service/latest_version/refresh.go +++ b/service/latest_version/refresh.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Refresh the Lookup with the provided overrides. @@ -35,7 +36,7 @@ func Refresh( return "", false, fmt.Errorf("lookup is nil") } - logFrom := util.LogFrom{Primary: "latest_version/refresh", Secondary: *lookup.GetStatus().ServiceID} + logFrom := logutil.LogFrom{Primary: "latest_version/refresh", Secondary: *lookup.GetStatus().ServiceID} // Whether this new semantic_version resolves differently than the current one. semanticVerDiff := semanticVersioning != nil && ( @@ -63,8 +64,8 @@ func Refresh( } // Log the lookup in use. - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("Refreshing with:\n%q", lookup.String(lookup, "")), logFrom, true) } diff --git a/service/latest_version/refresh_test.go b/service/latest_version/refresh_test.go index 7bfd8d63..44c7b934 100644 --- a/service/latest_version/refresh_test.go +++ b/service/latest_version/refresh_test.go @@ -26,14 +26,15 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestLookup_Refresh(t *testing.T) { testURL := testLookup("url", false).(*web.Lookup) - testURL.Query(true, util.LogFrom{}) + testURL.Query(true, logutil.LogFrom{}) testVersionURL := testURL.Status.LatestVersion() testGitHub := testLookup("github", false).(*github.Lookup) - testGitHub.Query(true, util.LogFrom{}) + testGitHub.Query(true, logutil.LogFrom{}) testVersionGitHub := testGitHub.Status.LatestVersion() type args struct { diff --git a/service/latest_version/types.go b/service/latest_version/types.go index ef9a8e27..0abef2e9 100644 --- a/service/latest_version/types.go +++ b/service/latest_version/types.go @@ -20,17 +20,13 @@ import ( "fmt" "strings" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/types/base" "github.com/release-argus/Argus/service/latest_version/types/github" "github.com/release-argus/Argus/service/latest_version/types/web" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" - "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" -) - -var ( - jLog *util.JLog ) // Lookup provides methods for retrieving the latest version of a service. diff --git a/service/latest_version/types/base/base.go b/service/latest_version/types/base/base.go index 9e0594d2..7ca0f738 100644 --- a/service/latest_version/types/base/base.go +++ b/service/latest_version/types/base/base.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Lookup is the base struct for a Lookup. @@ -154,6 +155,6 @@ func (l *Lookup) Inherit(fromLookup Interface) { } // Query will query the service for the latest version. -func (l *Lookup) Query(_ bool, _ util.LogFrom) (bool, error) { +func (l *Lookup) Query(_ bool, _ logutil.LogFrom) (bool, error) { return false, errors.New("not implemented") } diff --git a/service/latest_version/types/base/base_test.go b/service/latest_version/types/base/base_test.go index 9132a2d4..e9d1814d 100644 --- a/service/latest_version/types/base/base_test.go +++ b/service/latest_version/types/base/base_test.go @@ -22,12 +22,14 @@ import ( "testing" "time" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/filter" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) func TestInit(t *testing.T) { @@ -556,7 +558,7 @@ func TestQuery(t *testing.T) { URL: "https://example.com"}} // WHEN Query is called - gotBool, gotErr := l.Query(true, util.LogFrom{}) + gotBool, gotErr := l.Query(true, logutil.LogFrom{}) // THEN the function returns false and an error as it is not implemented if gotBool != false { diff --git a/service/latest_version/types/base/help_test.go b/service/latest_version/types/base/help_test.go index 23ed4fa0..2f9a1a38 100644 --- a/service/latest_version/types/base/help_test.go +++ b/service/latest_version/types/base/help_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import ( "os" "testing" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) type testLookup struct { @@ -30,9 +30,8 @@ type testLookup struct { func TestMain(m *testing.M) { // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - LogInit(jLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/service/latest_version/types/base/init.go b/service/latest_version/types/base/init.go deleted file mode 100644 index b11ef932..00000000 --- a/service/latest_version/types/base/init.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright [2024] [Argus] -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package base provides the base struct for latest_version lookups. -package base - -import "github.com/release-argus/Argus/util" - -var ( - jLog *util.JLog -) - -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} diff --git a/service/latest_version/types/base/interface.go b/service/latest_version/types/base/interface.go index 41cd661d..3ba2c23c 100644 --- a/service/latest_version/types/base/interface.go +++ b/service/latest_version/types/base/interface.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import ( "github.com/release-argus/Argus/service/latest_version/filter" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Lookup provides methods for retrieving the latest version of a service. @@ -36,7 +36,7 @@ type Interface interface { CheckValues(errPrefix string) (errs error) // Query the Lookup for the latest version. - Query(metrics bool, logFrom util.LogFrom) (newVersion bool, err error) + Query(metrics bool, logFrom logutil.LogFrom) (newVersion bool, err error) // Inherit state values from `fromLookup` if the values should query the same data. Inherit(fromLookup Interface) diff --git a/service/latest_version/types/base/metric_test.go b/service/latest_version/types/base/metric_test.go index 15c9ebfd..84d72986 100644 --- a/service/latest_version/types/base/metric_test.go +++ b/service/latest_version/types/base/metric_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" metric "github.com/release-argus/Argus/web/metric" diff --git a/service/latest_version/types/base/query.go b/service/latest_version/types/base/query.go index 6e844555..f18c7c87 100644 --- a/service/latest_version/types/base/query.go +++ b/service/latest_version/types/base/query.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +19,8 @@ import ( "fmt" "github.com/Masterminds/semver/v3" - "github.com/release-argus/Argus/util" + + logutil "github.com/release-argus/Argus/util/log" ) // VerifySemanticVersioning checks whether `newVersion` is a valid semantic version, @@ -27,13 +28,13 @@ import ( // // It returns an error if `newVersion` is not a valid semantic version, // or if it is older than `currentVersion`. -func (l *Lookup) VerifySemanticVersioning(newVersion, currentVersion string, logFrom util.LogFrom) error { +func (l *Lookup) VerifySemanticVersioning(newVersion, currentVersion string, logFrom logutil.LogFrom) error { // Check it is a valid semantic version. semNewVersion, err := semver.NewVersion(newVersion) if err != nil { err = fmt.Errorf("failed converting %q to a semantic version. If all versions are in this style, consider adding url_commands to get the version into the style of 'MAJOR.MINOR.PATCH' (https://semver.org/), or disabling semantic versioning (globally with defaults.service.semantic_versioning or just for this service with the semantic_versioning var)", newVersion) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return err } @@ -49,7 +50,7 @@ func (l *Lookup) VerifySemanticVersioning(newVersion, currentVersion string, log // oldVersion = 1.2.10 err := fmt.Errorf("queried version %q is less than the deployed version %q", newVersion, deployedVersion) - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return err } } @@ -59,7 +60,7 @@ func (l *Lookup) VerifySemanticVersioning(newVersion, currentVersion string, log } // HandleNewVersion handles a new version, updating the status, and logging the event. -func (l *Lookup) HandleNewVersion(version, releaseDate string, logFrom util.LogFrom) (bool, error) { +func (l *Lookup) HandleNewVersion(version, releaseDate string, logFrom logutil.LogFrom) (bool, error) { // Found a new version, so reset regex misses. l.Status.ResetRegexMisses() @@ -70,7 +71,7 @@ func (l *Lookup) HandleNewVersion(version, releaseDate string, logFrom util.LogF l.Status.SetDeployedVersion(version, "", true) } msg := fmt.Sprintf("Latest Release - %q", version) - jLog.Info(msg, logFrom, true) + logutil.Log.Info(msg, logFrom, true) l.Status.AnnounceFirstVersion() // Don't notify on first version. @@ -80,6 +81,6 @@ func (l *Lookup) HandleNewVersion(version, releaseDate string, logFrom util.LogF // New version found. l.Status.SetLatestVersion(version, "", true) msg := fmt.Sprintf("New Release - %q", version) - jLog.Info(msg, logFrom, true) + logutil.Log.Info(msg, logFrom, true) return true, nil } diff --git a/service/latest_version/types/base/query_test.go b/service/latest_version/types/base/query_test.go index 15673831..cc000ad3 100644 --- a/service/latest_version/types/base/query_test.go +++ b/service/latest_version/types/base/query_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestVerifySemanticVersioning(t *testing.T) { @@ -75,7 +76,7 @@ func TestVerifySemanticVersioning(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - logFrom := util.LogFrom{Primary: "TestVerifySemanticVersioning", Secondary: name} + logFrom := logutil.LogFrom{Primary: "TestVerifySemanticVersioning", Secondary: name} lookup := &Lookup{ Status: &status.Status{}, } @@ -156,7 +157,7 @@ func TestLookup_HandleNewVersion(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - logFrom := util.LogFrom{Primary: "TestLookup_HandleNewVersion", Secondary: name} + logFrom := logutil.LogFrom{Primary: "TestLookup_HandleNewVersion", Secondary: name} lookup := &Lookup{ Status: &status.Status{}, } diff --git a/service/latest_version/types/github/api_type/types.go b/service/latest_version/types/github/api_type/types.go index 6b3a3ead..fb761013 100644 --- a/service/latest_version/types/github/api_type/types.go +++ b/service/latest_version/types/github/api_type/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package types import ( "github.com/Masterminds/semver/v3" + "github.com/release-argus/Argus/util" ) diff --git a/service/latest_version/types/github/api_type/types_test.go b/service/latest_version/types/github/api_type/types_test.go index 8af090c2..3154de65 100644 --- a/service/latest_version/types/github/api_type/types_test.go +++ b/service/latest_version/types/github/api_type/types_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use 10s file except in compliance with the License. @@ -20,6 +20,7 @@ import ( "testing" "github.com/Masterminds/semver/v3" + "github.com/release-argus/Argus/test" ) diff --git a/service/latest_version/types/github/github.go b/service/latest_version/types/github/github.go index 0930a70a..97b363c9 100644 --- a/service/latest_version/types/github/github.go +++ b/service/latest_version/types/github/github.go @@ -21,8 +21,9 @@ import ( "sort" "github.com/Masterminds/semver/v3" + github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // insertionSort performs an 'insertion sort' of the given `release` into the `filteredReleases` slice. @@ -57,7 +58,7 @@ func insertionSort(release github_types.Release, filteredReleases *[]github_type // - // // Returns the filtered list, sorted in descending order (if semantic-versioning wanted). -func (l *Lookup) filterGitHubReleases(logFrom util.LogFrom) []github_types.Release { +func (l *Lookup) filterGitHubReleases(logFrom logutil.LogFrom) []github_types.Release { semanticVersioning := l.Options.GetSemanticVersioning() usePreReleases := l.usePreRelease() @@ -109,13 +110,13 @@ func (l *Lookup) filterGitHubReleases(logFrom util.LogFrom) []github_types.Relea } // checkGitHubReleasesBody validates that the response body conforms to the JSON formatting. -func (l *Lookup) checkGitHubReleasesBody(body []byte, logFrom util.LogFrom) ([]github_types.Release, error) { +func (l *Lookup) checkGitHubReleasesBody(body []byte, logFrom logutil.LogFrom) ([]github_types.Release, error) { var releases []github_types.Release if err := json.Unmarshal(body, &releases); err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) err = fmt.Errorf("unmarshal of GitHub API data failed\n%w", err) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } diff --git a/service/latest_version/types/github/github_test.go b/service/latest_version/types/github/github_test.go index af07dda9..45901d00 100644 --- a/service/latest_version/types/github/github_test.go +++ b/service/latest_version/types/github/github_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,10 +23,12 @@ import ( "testing" "github.com/Masterminds/semver/v3" + "github.com/release-argus/Argus/service/latest_version/filter" github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestInsertionSort(t *testing.T) { @@ -190,7 +192,7 @@ func TestLookup_FilterGitHubReleases(t *testing.T) { lv.GetGitHubData().SetReleases(tc.releases) // WHEN filterGitHubReleases is called on this body - filteredReleases := lv.filterGitHubReleases(util.LogFrom{}) + filteredReleases := lv.filterGitHubReleases(logutil.LogFrom{}) // THEN only the expected releases are kept if len(tc.want) != len(filteredReleases) { @@ -240,7 +242,7 @@ func TestLookup_CheckGitHubReleasesBody(t *testing.T) { lv := Lookup{} // WHEN filterGitHubReleases is called on this body - releases, err := lv.checkGitHubReleasesBody(body, util.LogFrom{}) + releases, err := lv.checkGitHubReleasesBody(body, logutil.LogFrom{}) // THEN it errors when expected e := util.ErrorToString(err) diff --git a/service/latest_version/types/github/githubdata.go b/service/latest_version/types/github/githubdata.go index 8fb0fbdd..ce066334 100644 --- a/service/latest_version/types/github/githubdata.go +++ b/service/latest_version/types/github/githubdata.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import ( "github.com/release-argus/Argus/service/latest_version/types/base" github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) var ( @@ -45,7 +46,7 @@ func SetEmptyListETag(accessToken string) { lookup.data.SetTagFallback() //#nosec G104 -- Disregard. //nolint:errcheck // ^ - lookup.httpRequest(util.LogFrom{Primary: "SetEmptyListETag"}) + lookup.httpRequest(logutil.LogFrom{Primary: "SetEmptyListETag"}) setEmptyListETag(lookup.data.ETag()) } diff --git a/service/latest_version/types/github/help_test.go b/service/latest_version/types/github/help_test.go index 59fae231..4aaf93a4 100644 --- a/service/latest_version/types/github/help_test.go +++ b/service/latest_version/types/github/help_test.go @@ -23,13 +23,12 @@ import ( "testing" dbtype "github.com/release-argus/Argus/db/types" - "github.com/release-argus/Argus/service/latest_version/filter" "github.com/release-argus/Argus/service/latest_version/types/base" github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Unsure why Go tests give a different result than the compiled binary @@ -48,12 +47,9 @@ var testBody = []byte(test.TrimJSON(` var testBodyObject []github_types.Release func TestMain(m *testing.M) { - // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - base.LogInit(jLog) - LogInit(jLog) - filter.LogInit(jLog) + // initialise logutil.Log + logutil.Init("DEBUG", false) + logutil.Log.Testing = true SetEmptyListETag(os.Getenv("GITHUB_TOKEN")) initialEmptyListETag = getEmptyListETag() diff --git a/service/latest_version/types/github/init.go b/service/latest_version/types/github/init.go index 98590fb8..3159b90f 100644 --- a/service/latest_version/types/github/init.go +++ b/service/latest_version/types/github/init.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,14 +19,8 @@ import ( "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" - "github.com/release-argus/Argus/util" ) -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} - // Init the Lookup, assigning Defaults, and initialising child structs. func (l *Lookup) Init( options *opt.Options, diff --git a/service/latest_version/types/github/init_test.go b/service/latest_version/types/github/init_test.go index b071d821..70d42791 100644 --- a/service/latest_version/types/github/init_test.go +++ b/service/latest_version/types/github/init_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,11 +20,12 @@ package github import ( "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "gopkg.in/yaml.v3" ) func TestInit(t *testing.T) { diff --git a/service/latest_version/types/github/query.go b/service/latest_version/types/github/query.go index f56e852f..650bee4c 100644 --- a/service/latest_version/types/github/query.go +++ b/service/latest_version/types/github/query.go @@ -27,6 +27,7 @@ import ( github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Query queries the source, @@ -34,7 +35,7 @@ import ( // // Parameters: // - metrics: if true, set Prometheus metrics based on the query. -func (l *Lookup) Query(metrics bool, logFrom util.LogFrom) (bool, error) { +func (l *Lookup) Query(metrics bool, logFrom logutil.LogFrom) (bool, error) { newVersion, err := l.query(logFrom, 0) if metrics { @@ -50,7 +51,7 @@ func (l *Lookup) Query(metrics bool, logFrom util.LogFrom) (bool, error) { // Parameters: // // checkNumber: 0 for first check, 1 for second check (if the first check found a new version). -func (l *Lookup) query(logFrom util.LogFrom, checkNumber int) (bool, error) { +func (l *Lookup) query(logFrom logutil.LogFrom, checkNumber int) (bool, error) { body, err := l.httpRequest(logFrom) if err != nil { return false, err @@ -59,7 +60,7 @@ func (l *Lookup) query(logFrom util.LogFrom, checkNumber int) (bool, error) { // Get the latest version, and its release date from the body. version, releaseDate, err := l.getVersion(body, logFrom) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return false, err } @@ -89,7 +90,7 @@ func (l *Lookup) query(logFrom util.LogFrom, checkNumber int) (bool, error) { } // httpRequest makes a HTTP GET request to the URL of this Lookup, and returns the body retrieved. -func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) httpRequest(logFrom logutil.LogFrom) ([]byte, error) { req, err := l.createRequest(logFrom) if err != nil { return nil, err @@ -104,11 +105,11 @@ func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { } // createRequest returns a HTTP GET request to the URL of this Lookup. -func (l *Lookup) createRequest(logFrom util.LogFrom) (*http.Request, error) { +func (l *Lookup) createRequest(logFrom logutil.LogFrom) (*http.Request, error) { req, err := http.NewRequest(http.MethodGet, l.url(), nil) if err != nil { err = fmt.Errorf("failed creating http request for %q: %w", l.URL, err) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } @@ -129,12 +130,12 @@ func (l *Lookup) createRequest(logFrom util.LogFrom) (*http.Request, error) { } // getResponse will make the request, and return the response, response body, and any errors encountered. -func (l *Lookup) getResponse(req *http.Request, logFrom util.LogFrom) (*http.Response, []byte, error) { +func (l *Lookup) getResponse(req *http.Request, logFrom logutil.LogFrom) (*http.Response, []byte, error) { // Make the request. client := &http.Client{} resp, err := client.Do(req) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, nil, err //nolint:wrapcheck } @@ -142,7 +143,7 @@ func (l *Lookup) getResponse(req *http.Request, logFrom util.LogFrom) (*http.Res defer resp.Body.Close() body, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20)) // Limit to 10 MB. if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, nil, err //nolint:wrapcheck } return resp, body, nil @@ -154,7 +155,7 @@ func (l *Lookup) getResponse(req *http.Request, logFrom util.LogFrom) (*http.Res // - 304 Not Modified, it flips the tags flag, performs a query on the "/tags" endpoint, and returns that body. // - 401 Unauthorized, 403 Forbidden, and 429 Too Many Requests, it logs the error, and returns a nil body. // - unknown status code, it logs the error, and returns a nil body along with an error. -func (l *Lookup) handleResponse(resp *http.Response, body []byte, logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) handleResponse(resp *http.Response, body []byte, logFrom logutil.LogFrom) ([]byte, error) { switch resp.StatusCode { // 200 - Resource has changed. case http.StatusOK: @@ -179,7 +180,7 @@ func (l *Lookup) handleResponse(resp *http.Response, body []byte, logFrom util.L // Unknown status code. err := fmt.Errorf("unknown status code %d\n%s", resp.StatusCode, string(body)) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } @@ -187,7 +188,7 @@ func (l *Lookup) handleResponse(resp *http.Response, body []byte, logFrom util.L // and return any errors from the possible tag fallback request. // // 200 when the ETag changed. -func (l *Lookup) handleStatusOK(resp *http.Response, body []byte, logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) handleStatusOK(resp *http.Response, body []byte, logFrom logutil.LogFrom) ([]byte, error) { newETag := strings.TrimPrefix(resp.Header.Get("etag"), "W/") l.data.SetETag(newETag) @@ -201,7 +202,7 @@ func (l *Lookup) handleStatusOK(resp *http.Response, body []byte, logFrom util.L // Flip the fallback flag. l.data.SetTagFallback() if l.data.TagFallback() { - jLog.Verbose( + logutil.Log.Verbose( fmt.Sprintf("/releases gave %s, trying /tags", body), logFrom, true) body, err := l.httpRequest(logFrom) @@ -211,7 +212,7 @@ func (l *Lookup) handleStatusOK(resp *http.Response, body []byte, logFrom util.L // Has tags/releases. } else { msg := fmt.Sprintf("Potentially found new releases (new ETag %s)", newETag) - jLog.Verbose(msg, logFrom, true) + logutil.Log.Verbose(msg, logFrom, true) } return body, nil } @@ -220,13 +221,13 @@ func (l *Lookup) handleStatusOK(resp *http.Response, body []byte, logFrom util.L // and return any errors from the possible tag fallback request. // // 304 when the ETag is unchanged and the response body is empty. -func (l *Lookup) handleStatusNotModified(logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) handleStatusNotModified(logFrom logutil.LogFrom) ([]byte, error) { // Didn't find any releases before and nothing has changed? if !l.data.hasReleases() { // Flip the fallback flag for next time. l.data.SetTagFallback() if l.data.TagFallback() { - jLog.Verbose("no tags found on /releases, trying /tags", logFrom, true) + logutil.Log.Verbose("no tags found on /releases, trying /tags", logFrom, true) body, err := l.httpRequest(logFrom) return body, err } @@ -239,7 +240,7 @@ func (l *Lookup) handleStatusNotModified(logFrom util.LogFrom) ([]byte, error) { // handleStatusUnauthorized will handle a 401 status code response. // // 401 when the access token is invalid. -func (l *Lookup) handleStatusUnauthorized(body []byte, logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) handleStatusUnauthorized(body []byte, logFrom logutil.LogFrom) ([]byte, error) { bodyStr := string(body) var err error @@ -250,7 +251,7 @@ func (l *Lookup) handleStatusUnauthorized(body []byte, logFrom util.LogFrom) ([] // Unknown error. err = fmt.Errorf("unknown 401 response\n%s", bodyStr) } - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } @@ -258,7 +259,7 @@ func (l *Lookup) handleStatusUnauthorized(body []byte, logFrom util.LogFrom) ([] // handleStatusForbidden will handle a 403 status code response. // // 403 when the rate limit is exceeded. -func (l *Lookup) handleStatusForbidden(body []byte, logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) handleStatusForbidden(body []byte, logFrom logutil.LogFrom) ([]byte, error) { bodyStr := string(body) var err error @@ -266,17 +267,17 @@ func (l *Lookup) handleStatusForbidden(body []byte, logFrom util.LogFrom) ([]byt // Check for rate limit. case strings.Contains(bodyStr, "rate limit"): err = errors.New("rate limit reached for GitHub") - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) // Missing tag_name. case !strings.Contains(bodyStr, `"tag_name"`): err = fmt.Errorf("tag_name not found at %s\n%s", l.URL, bodyStr) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) // Other. default: err = fmt.Errorf("unknown 403 response\n%s", bodyStr) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) } return nil, err @@ -285,11 +286,11 @@ func (l *Lookup) handleStatusForbidden(body []byte, logFrom util.LogFrom) ([]byt // handleStatusTooManyRequests handles a 429 status code response. // // 429 when too many requests made within a short period. -func (l *Lookup) handleStatusTooManyRequests(body []byte, logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) handleStatusTooManyRequests(body []byte, logFrom logutil.LogFrom) ([]byte, error) { var message github_types.Message if err := json.Unmarshal(body, &message); err != nil { err = fmt.Errorf("unmarshal of GitHub API data failed\n%w", err) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, errors.New("too many requests made to GitHub") } @@ -298,7 +299,7 @@ func (l *Lookup) handleStatusTooManyRequests(body []byte, logFrom util.LogFrom) // releaseMeetsRequirements verifies that the `release` meets the requirements of the Lookup // and returns the version, and its release date if it does. -func (l *Lookup) releaseMeetsRequirements(release github_types.Release, logFrom util.LogFrom) (string, string, error) { +func (l *Lookup) releaseMeetsRequirements(release github_types.Release, logFrom logutil.LogFrom) (string, string, error) { version := release.TagName if release.SemanticVersion != nil { version = release.SemanticVersion.String() @@ -309,7 +310,7 @@ func (l *Lookup) releaseMeetsRequirements(release github_types.Release, logFrom if l.Require == nil { // Verify that date is in RFC3339 format. if _, err := time.Parse(time.RFC3339, releaseDate); err != nil { - jLog.Warn( + logutil.Log.Warn( fmt.Errorf("ignoring release date of %q for version %q on %q as it's not in RFC3339 format\n%w", releaseDate, version, l.GetServiceID(), err), logFrom, true) @@ -342,11 +343,11 @@ func (l *Lookup) releaseMeetsRequirements(release github_types.Release, logFrom if strings.HasSuffix(err.Error(), "\n") { err = errors.New(strings.TrimSuffix(err.Error(), "\n")) } - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return "", "", err // else if the tag does exist (and we did search for one). } else if l.Require.Docker != nil { - jLog.Info( + logutil.Log.Info( fmt.Sprintf(`found %s container "%s:%s"`, l.Require.Docker.GetType(), l.Require.Docker.Image, l.Require.Docker.GetTag(version)), logFrom, true) @@ -354,7 +355,7 @@ func (l *Lookup) releaseMeetsRequirements(release github_types.Release, logFrom // Verify date is in RFC3339 format. if _, err := time.Parse(time.RFC3339, releaseDate); err != nil { - jLog.Warn( + logutil.Log.Warn( fmt.Errorf("ignoring release date of %q for version %q on %q as it's not in RFC3339 format\n%w", releaseDate, version, l.GetServiceID(), err), logFrom, true) @@ -366,7 +367,7 @@ func (l *Lookup) releaseMeetsRequirements(release github_types.Release, logFrom // getVersion returns the version, and date of the matching asset/release from `body` // that matches the URLCommands, and Regex requirements. -func (l *Lookup) getVersion(body []byte, logFrom util.LogFrom) (string, string, error) { +func (l *Lookup) getVersion(body []byte, logFrom logutil.LogFrom) (string, string, error) { // body length = 0 if GitHub ETag unchanged. if len(body) != 0 { if err := l.setReleases(body, logFrom); err != nil { @@ -374,7 +375,7 @@ func (l *Lookup) getVersion(body []byte, logFrom util.LogFrom) (string, string, } } else { // Recheck this ETag's filteredReleases in case filters/releases changed. - jLog.Verbose("Using cached releases (ETag unchanged)", logFrom, true) + logutil.Log.Verbose("Using cached releases (ETag unchanged)", logFrom, true) } filteredReleases := l.filterGitHubReleases(logFrom) if len(filteredReleases) == 0 { @@ -395,7 +396,7 @@ func (l *Lookup) getVersion(body []byte, logFrom util.LogFrom) (string, string, } // setReleases processes, and stores the provided GitHub releases data. -func (l *Lookup) setReleases(body []byte, logFrom util.LogFrom) error { +func (l *Lookup) setReleases(body []byte, logFrom logutil.LogFrom) error { releases, err := l.checkGitHubReleasesBody(body, logFrom) if err != nil { return err @@ -412,12 +413,12 @@ func (l *Lookup) handleNewVersion( version, releaseDate, latestVersion string, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) (bool, error) { // Verify that the version has changed. (GitHub may have just omitted the tag for some reason). if checkNumber == 0 { msg := fmt.Sprintf("Possibly found a new version (From %q to %q). Checking again", latestVersion, version) - jLog.Verbose(msg, logFrom, latestVersion != "") + logutil.Log.Verbose(msg, logFrom, latestVersion != "") time.Sleep(time.Second) return l.query(logFrom, 1) } @@ -426,9 +427,9 @@ func (l *Lookup) handleNewVersion( } // handleNoVersionChange handles the case of no version(s) being found. -func (l *Lookup) handleNoVersionChange(checkNumber int, version string, logFrom util.LogFrom) { +func (l *Lookup) handleNoVersionChange(checkNumber int, version string, logFrom logutil.LogFrom) { if checkNumber == 1 { - jLog.Verbose( + logutil.Log.Verbose( fmt.Sprintf("Staying on %q as that's the latest version in the second check", version), logFrom, true) } diff --git a/service/latest_version/types/github/query_test.go b/service/latest_version/types/github/query_test.go index a6387e84..fe4e0f5b 100644 --- a/service/latest_version/types/github/query_test.go +++ b/service/latest_version/types/github/query_test.go @@ -28,17 +28,19 @@ import ( "time" "github.com/Masterminds/semver/v3" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/filter" github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" + logutil "github.com/release-argus/Argus/util/log" ) func TestQuery(t *testing.T) { tLookup := testLookup(false) tLookup.URL = "release-argus/.github" - tLookup.Query(false, util.LogFrom{}) + tLookup.Query(false, logutil.LogFrom{}) emptyReleasesETag := tLookup.data.eTag type statusVars struct { @@ -297,7 +299,7 @@ func TestQuery(t *testing.T) { } // WHEN Query is called on it. - _, err = lookup.Query(true, util.LogFrom{}) + _, err = lookup.Query(true, logutil.LogFrom{}) // THEN any err is expected. stdout := releaseStdout() @@ -369,7 +371,7 @@ func TestHTTPRequest(t *testing.T) { } // WHEN httpRequest is called on it. - _, err := lookup.httpRequest(util.LogFrom{}) + _, err := lookup.httpRequest(logutil.LogFrom{}) // THEN any err is expected. e := util.ErrorToString(err) @@ -400,7 +402,7 @@ func TestGetResponse_ReadError(t *testing.T) { // WHEN getResponse is called on that URL. l := Lookup{} - _, _, err = l.getResponse(req, util.LogFrom{}) + _, _, err = l.getResponse(req, logutil.LogFrom{}) // THEN an error is expected from the read error. if err == nil { @@ -542,7 +544,7 @@ func TestHandleResponse(t *testing.T) { lookup.HardDefaults.AccessToken = "Something" } - logFrom := util.LogFrom{Primary: "TestHandleResponse", Secondary: name} + logFrom := logutil.LogFrom{Primary: "TestHandleResponse", Secondary: name} // WHEN handleResponse is called on it. gotBody, err := lookup.handleResponse(resp, tc.body, logFrom) @@ -735,7 +737,7 @@ func TestReleaseMeetsRequirements(t *testing.T) { if tc.releaseOverrides != nil { testRelease = *tc.releaseOverrides } - logFrom := util.LogFrom{Primary: "TestReleaseMeetsRequirements", Secondary: name} + logFrom := logutil.LogFrom{Primary: "TestReleaseMeetsRequirements", Secondary: name} // WHEN releaseMeetsRequirements is called on it. version, releaseDate, err := lookup.releaseMeetsRequirements(testRelease, logFrom) @@ -850,7 +852,7 @@ func TestGetVersion(t *testing.T) { lookup.Options, lookup.Status, lookup.Defaults, lookup.HardDefaults) - logFrom := util.LogFrom{Primary: "TestGetVersion", Secondary: name} + logFrom := logutil.LogFrom{Primary: "TestGetVersion", Secondary: name} testBody := body if tc.body != nil { testBody = []byte(*tc.body) @@ -923,7 +925,7 @@ func TestSetReleases(t *testing.T) { if err != nil { t.Fatalf("github.Lookup.setReleases failed to unmarshal overrides: %v", err) } - logFrom := util.LogFrom{Primary: "TestGetVersions", Secondary: name} + logFrom := logutil.LogFrom{Primary: "TestGetVersions", Secondary: name} testBody := body if tc.body != "" { testBody = []byte(tc.body) @@ -1032,7 +1034,7 @@ func TestQueryGitHubETag(t *testing.T) { lookup.Require = &filter.Require{} } - _, err := lookup.Query(true, util.LogFrom{}) + _, err := lookup.Query(true, logutil.LogFrom{}) if err != nil { errs = append(errs, err) } @@ -1090,7 +1092,7 @@ func TestHandleNoVersionChange(t *testing.T) { lookup := testLookup(false) // WHEN handleNoVersionChange is called on it. - lookup.handleNoVersionChange(tc.checkNumber, tc.version, util.LogFrom{}) + lookup.handleNoVersionChange(tc.checkNumber, tc.version, logutil.LogFrom{}) // THEN a message is printed when expected. stdout := releaseStdout() diff --git a/service/latest_version/types/github/refresh_test.go b/service/latest_version/types/github/refresh_test.go index f0612a78..d13b1de1 100644 --- a/service/latest_version/types/github/refresh_test.go +++ b/service/latest_version/types/github/refresh_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,12 +21,13 @@ import ( "testing" "time" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/filter" "github.com/release-argus/Argus/service/latest_version/types/base" github_types "github.com/release-argus/Argus/service/latest_version/types/github/api_type" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) func checkDockerToken(t *testing.T, gotQueryToken, wantQueryToken string, gotValidUntil, wantValidUntil time.Time, message string) { diff --git a/service/latest_version/types/github/types.go b/service/latest_version/types/github/types.go index 14de00ac..f38add5d 100644 --- a/service/latest_version/types/github/types.go +++ b/service/latest_version/types/github/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,15 +19,12 @@ import ( "encoding/json" "fmt" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" -) - -var ( - jLog *util.JLog ) // Lookup provides a GitHub-based lookup type. diff --git a/service/latest_version/types/github/types_test.go b/service/latest_version/types/github/types_test.go index 99a28e5d..099f165c 100644 --- a/service/latest_version/types/github/types_test.go +++ b/service/latest_version/types/github/types_test.go @@ -20,13 +20,14 @@ package github import ( "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/filter" "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) func TestLookup_String(t *testing.T) { diff --git a/service/latest_version/types/web/help_test.go b/service/latest_version/types/web/help_test.go index 75719727..0a75a646 100644 --- a/service/latest_version/types/web/help_test.go +++ b/service/latest_version/types/web/help_test.go @@ -21,21 +21,17 @@ import ( "testing" dbtype "github.com/release-argus/Argus/db/types" - "github.com/release-argus/Argus/service/latest_version/filter" "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { - // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - base.LogInit(jLog) - LogInit(jLog) - filter.LogInit(jLog) + // initialise logutil.Log + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/service/latest_version/types/web/init.go b/service/latest_version/types/web/init.go deleted file mode 100644 index dee05da2..00000000 --- a/service/latest_version/types/web/init.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright [2024] [Argus] -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package web provides a web-based lookup type. -package web - -import ( - "github.com/release-argus/Argus/util" -) - -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} diff --git a/service/latest_version/types/web/init_test.go b/service/latest_version/types/web/init_test.go index 6fd1b745..3f59290a 100644 --- a/service/latest_version/types/web/init_test.go +++ b/service/latest_version/types/web/init_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,11 +19,12 @@ package web import ( "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "gopkg.in/yaml.v3" ) func TestInit(t *testing.T) { diff --git a/service/latest_version/types/web/query.go b/service/latest_version/types/web/query.go index 70da8bd9..28bf9580 100644 --- a/service/latest_version/types/web/query.go +++ b/service/latest_version/types/web/query.go @@ -23,7 +23,7 @@ import ( "net/http" "strings" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Query queries the source, @@ -32,7 +32,7 @@ import ( // Parameters: // // metrics: if true, set Prometheus metrics based on the query. -func (l *Lookup) Query(metrics bool, logFrom util.LogFrom) (bool, error) { +func (l *Lookup) Query(metrics bool, logFrom logutil.LogFrom) (bool, error) { isNewVersion, err := l.query(logFrom) if metrics { @@ -44,7 +44,7 @@ func (l *Lookup) Query(metrics bool, logFrom util.LogFrom) (bool, error) { // Query queries the source, // and returns whether a new release was found, and updates LatestVersion if so. -func (l *Lookup) query(logFrom util.LogFrom) (bool, error) { +func (l *Lookup) query(logFrom logutil.LogFrom) (bool, error) { body, err := l.httpRequest(logFrom) if err != nil { return false, err @@ -52,7 +52,7 @@ func (l *Lookup) query(logFrom util.LogFrom) (bool, error) { version, err := l.getVersion(string(body), logFrom) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return false, err } @@ -78,7 +78,7 @@ func (l *Lookup) query(logFrom util.LogFrom) (bool, error) { } // httpRequest makes a HTTP GET request to the URL, and returns the body. -func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { +func (l *Lookup) httpRequest(logFrom logutil.LogFrom) ([]byte, error) { customTransport := &http.Transport{} // HTTPS insecure skip verify. if l.allowInvalidCerts() { @@ -91,7 +91,7 @@ func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { if err != nil { err = fmt.Errorf("failed creating http request for %q: %w", l.URL, err) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } @@ -104,22 +104,22 @@ func (l *Lookup) httpRequest(logFrom util.LogFrom) ([]byte, error) { // Don't crash on invalid certs. if strings.Contains(err.Error(), "x509") { err = fmt.Errorf("x509 (certificate invalid)") - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return nil, err } - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err } // Read the response body. defer resp.Body.Close() body, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20)) // Limit to 10 MB. - jLog.Error(err, logFrom, err != nil) + logutil.Log.Error(err, logFrom, err != nil) return body, err //nolint: wrapcheck } // getVersion returns the latest version from `body` that matches the URLCommands, and Regex requirements. -func (l *Lookup) getVersion(body string, logFrom util.LogFrom) (string, error) { +func (l *Lookup) getVersion(body string, logFrom logutil.LogFrom) (string, error) { filteredVersions, err := l.URLCommands.GetVersions(body, logFrom) if err != nil { return "", fmt.Errorf("no releases were found matching the url_commands\n%w", err) @@ -142,7 +142,7 @@ func (l *Lookup) getVersion(body string, logFrom util.LogFrom) (string, error) { } // versionMeetsRequirements checks whether `version` meets the requirements of the Lookup. -func (l *Lookup) versionMeetsRequirements(version, body string, logFrom util.LogFrom) error { +func (l *Lookup) versionMeetsRequirements(version, body string, logFrom logutil.LogFrom) error { // No `Require` filters. if l.Require == nil { return nil @@ -170,11 +170,11 @@ func (l *Lookup) versionMeetsRequirements(version, body string, logFrom util.Log if strings.HasSuffix(errStr, "\n") { err = errors.New(strings.TrimSuffix(errStr, "\n")) } - jLog.Warn(err, logFrom, true) + logutil.Log.Warn(err, logFrom, true) return err // Docker image:tag does exist. } else if l.Require.Docker != nil { - jLog.Info( + logutil.Log.Info( fmt.Sprintf(`found %s container "%s:%s"`, l.Require.Docker.GetType(), l.Require.Docker.Image, l.Require.Docker.GetTag(version)), logFrom, true) diff --git a/service/latest_version/types/web/query_test.go b/service/latest_version/types/web/query_test.go index e42d76e8..e09a8979 100644 --- a/service/latest_version/types/web/query_test.go +++ b/service/latest_version/types/web/query_test.go @@ -24,11 +24,13 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/testutil" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/filter" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" metric "github.com/release-argus/Argus/web/metric" - "gopkg.in/yaml.v3" ) func TestHTTPRequest(t *testing.T) { @@ -62,7 +64,7 @@ func TestHTTPRequest(t *testing.T) { } // WHEN httpRequest is called on it. - _, err := lookup.httpRequest(util.LogFrom{}) + _, err := lookup.httpRequest(logutil.LogFrom{}) // THEN any err is expected. e := util.ErrorToString(err) @@ -273,7 +275,7 @@ func TestGetVersion(t *testing.T) { // WHEN getVersion is called on it. version, err := lookup.getVersion( - testBody, util.LogFrom{}) + testBody, logutil.LogFrom{}) // THEN any err is expected. e := util.ErrorToString(err) @@ -292,7 +294,7 @@ func TestGetVersion(t *testing.T) { func TestQuery(t *testing.T) { testLookupVersions := testLookup(false) - testLookupVersions.query(util.LogFrom{}) + testLookupVersions.query(logutil.LogFrom{}) type statusVars struct { latestVersion, latestVersionWant string @@ -562,7 +564,7 @@ func TestQuery(t *testing.T) { // WHEN Query is called on it. var newVersion bool - newVersion, err = lookup.Query(true, util.LogFrom{}) + newVersion, err = lookup.Query(true, logutil.LogFrom{}) // THEN any err is expected. stdout := releaseStdout() diff --git a/service/latest_version/types/web/types.go b/service/latest_version/types/web/types.go index 55f09a5e..c85772c2 100644 --- a/service/latest_version/types/web/types.go +++ b/service/latest_version/types/web/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,15 +19,12 @@ import ( "encoding/json" "fmt" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" -) - -var ( - jLog *util.JLog ) // Lookup is a web-based lookup type. diff --git a/service/latest_version/types/web/types_test.go b/service/latest_version/types/web/types_test.go index 3be3ea23..8bbd9d3b 100644 --- a/service/latest_version/types/web/types_test.go +++ b/service/latest_version/types/web/types_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,12 +19,13 @@ package web import ( "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/service/latest_version/types/base" opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) func TestNew(t *testing.T) { diff --git a/service/new.go b/service/new.go index 971571d3..cadee868 100644 --- a/service/new.go +++ b/service/new.go @@ -27,6 +27,7 @@ import ( latestver "github.com/release-argus/Argus/service/latest_version" "github.com/release-argus/Argus/service/latest_version/types/github" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -72,7 +73,7 @@ func FromPayload( webhookGlobals *webhook.SliceDefaults, webhookDefaults, webhookHardDefaults *webhook.Defaults, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) (*Service, error) { var buf bytes.Buffer if _, err := buf.ReadFrom(*payload); err != nil { @@ -96,8 +97,8 @@ func FromPayload( err = dec1.Decode(newService) } if err != nil { - jLog.Error(err, logFrom, true) - jLog.Verbose( + logutil.Log.Error(err, logFrom, true) + logutil.Log.Verbose( fmt.Sprintf("Payload: %s", buf.String()), logFrom, true) return nil, err //nolint:wrapcheck @@ -108,7 +109,7 @@ func FromPayload( dec2 := json.NewDecoder(bytes.NewReader(buf.Bytes())) var secretRefs oldSecretRefs if err := dec2.Decode(&secretRefs); err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return nil, err //nolint:wrapcheck } @@ -329,7 +330,7 @@ func (s *Service) CheckFetches() error { s.Status.DatabaseChannel = databaseChannel }() - logFrom := util.LogFrom{Primary: s.ID, Secondary: "CheckFetches"} + logFrom := logutil.LogFrom{Primary: s.ID, Secondary: "CheckFetches"} // Fetch latest version. { diff --git a/service/new_test.go b/service/new_test.go index e4047171..159870ef 100644 --- a/service/new_test.go +++ b/service/new_test.go @@ -36,6 +36,7 @@ import ( "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -3273,9 +3274,9 @@ func TestService_GiveSecrets(t *testing.T) { func TestService_CheckFetches(t *testing.T) { // GIVEN a Service testLV := testLatestVersion(t, "url", false) - testLV.Query(false, util.LogFrom{}) + testLV.Query(false, logutil.LogFrom{}) testDVL := testDeployedVersionLookup(t, false) - v, _ := testDVL.Query(false, util.LogFrom{}) + v, _ := testDVL.Query(false, logutil.LogFrom{}) testDVL.Status.SetDeployedVersion(v, "", false) tests := map[string]struct { svc *Service @@ -3659,7 +3660,7 @@ func TestFromPayload_ReadFromFail(t *testing.T) { &shoutrrr.SliceDefaults{}, &shoutrrr.SliceDefaults{}, &webhook.SliceDefaults{}, &webhook.Defaults{}, &webhook.Defaults{}, - util.LogFrom{}, + logutil.LogFrom{}, ) // THEN we should get an error @@ -4493,7 +4494,7 @@ func TestFromPayload(t *testing.T) { tc.webhookGlobals, tc.webhookDefaults, tc.webhookHardDefaults, - util.LogFrom{Primary: name}) + logutil.LogFrom{Primary: name}) // THEN we get an error if the payload is invalid if tc.errRegex != "" || err != nil { diff --git a/service/status/status_test.go b/service/status/status_test.go index 22b21745..7b1bd83a 100644 --- a/service/status/status_test.go +++ b/service/status/status_test.go @@ -22,6 +22,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/testutil" + dbtype "github.com/release-argus/Argus/db/types" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" diff --git a/service/track.go b/service/track.go index 7e9414e8..82f7e0cb 100644 --- a/service/track.go +++ b/service/track.go @@ -20,7 +20,7 @@ import ( "sync" "time" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web/metric" ) @@ -52,8 +52,8 @@ func (s *Service) Track() { } // Track forever. - logFrom := util.LogFrom{Primary: s.ID} - jLog.Verbose( + logFrom := logutil.LogFrom{Primary: s.ID} + logutil.Log.Verbose( fmt.Sprintf("Tracking %s at %s every %s", s.ID, s.LatestVersion.ServiceURL(true), s.Options.GetInterval()), logFrom, diff --git a/service/track_test.go b/service/track_test.go index 06d1841c..61c75253 100644 --- a/service/track_test.go +++ b/service/track_test.go @@ -23,20 +23,22 @@ import ( "time" "github.com/prometheus/client_golang/prometheus/testutil" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/latest_version/types/web" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" "github.com/release-argus/Argus/web/metric" "github.com/release-argus/Argus/webhook" webhook_test "github.com/release-argus/Argus/webhook/test" - "gopkg.in/yaml.v3" ) func TestService_Track(t *testing.T) { testURLService := testService(t, "TestService_Track", "url") - testURLService.LatestVersion.Query(false, util.LogFrom{}) + testURLService.LatestVersion.Query(false, logutil.LogFrom{}) testURLLatestVersion := testURLService.Status.LatestVersion() type overrides struct { diff --git a/service/types.go b/service/types.go index 877a1f86..b8d7c7e2 100644 --- a/service/types.go +++ b/service/types.go @@ -20,6 +20,8 @@ import ( "fmt" "strings" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/notify/shoutrrr" deployedver "github.com/release-argus/Argus/service/deployed_version" @@ -30,11 +32,6 @@ import ( "github.com/release-argus/Argus/util" apitype "github.com/release-argus/Argus/web/api/types" "github.com/release-argus/Argus/webhook" - "gopkg.in/yaml.v3" -) - -var ( - jLog *util.JLog ) // Slice is a slice mapping of Service. diff --git a/service/types_test.go b/service/types_test.go index 19eb0573..12e91d7c 100644 --- a/service/types_test.go +++ b/service/types_test.go @@ -20,6 +20,8 @@ import ( "strings" "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/notify/shoutrrr" deployedver "github.com/release-argus/Argus/service/deployed_version" @@ -34,7 +36,6 @@ import ( "github.com/release-argus/Argus/util" apitype "github.com/release-argus/Argus/web/api/types" "github.com/release-argus/Argus/webhook" - "gopkg.in/yaml.v3" ) func TestSlice_UnmarshalJSON(t *testing.T) { diff --git a/testing/command.go b/testing/command.go index 751fc477..747c0700 100644 --- a/testing/command.go +++ b/testing/command.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,30 +21,26 @@ import ( "strings" "github.com/release-argus/Argus/config" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // CommandTest will test the commands given to a Service. -func CommandTest( - flag *string, - cfg *config.Config, - log *util.JLog, -) { +func CommandTest(flag *string, cfg *config.Config) { // Only if flag provided. if *flag == "" { return } - logFrom := util.LogFrom{Primary: "Testing", Secondary: *flag} + logFrom := logutil.LogFrom{Primary: "Testing", Secondary: *flag} // Log the test details. - log.Info( + logutil.Log.Info( "", logFrom, true) service, exist := cfg.Service[*flag] if !exist { - log.Fatal( + logutil.Log.Fatal( fmt.Sprintf( "Service %q could not be found in config.service\nDid you mean one of these?\n - %s", *flag, strings.Join(cfg.Order, "\n - "), @@ -54,7 +50,7 @@ func CommandTest( } if service.CommandController == nil { - log.Fatal( + logutil.Log.Fatal( fmt.Sprintf( "Service %q does not have any `command` defined", *flag), @@ -65,7 +61,7 @@ func CommandTest( //#nosec G104 -- Disregard. //nolint:errcheck // ^ service.CommandController.Exec(logFrom) - if !log.Testing { + if !logutil.Log.Testing { os.Exit(0) } } diff --git a/testing/command_test.go b/testing/command_test.go index c568c4bd..e901131c 100644 --- a/testing/command_test.go +++ b/testing/command_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -136,7 +136,7 @@ func TestCommandTest(t *testing.T) { Service: tc.slice, Order: order, } - CommandTest(&tc.flag, &cfg, jLog) + CommandTest(&tc.flag, &cfg) // THEN we get the expected stdout stdout := releaseStdout() diff --git a/testing/help_test.go b/testing/help_test.go index ecc9fee6..da800fe6 100644 --- a/testing/help_test.go +++ b/testing/help_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,17 +20,13 @@ import ( "os" "testing" - "github.com/release-argus/Argus/config" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) -var jLog *util.JLog - func TestMain(m *testing.M) { // initialise jLog - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - config.LogInit(jLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/testing/service.go b/testing/service.go index f0553fad..67f768c6 100644 --- a/testing/service.go +++ b/testing/service.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,22 +22,19 @@ import ( "github.com/release-argus/Argus/config" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // ServiceTest queries the service and returns the found version. -func ServiceTest( - flag *string, - cfg *config.Config, - log *util.JLog, -) { +func ServiceTest(flag *string, cfg *config.Config) { // Only if flag provided. if *flag == "" { return } // Log the test details. - logFrom := util.LogFrom{Primary: "Testing", Secondary: *flag} - log.Info( + logFrom := logutil.LogFrom{Primary: "Testing", Secondary: *flag} + logutil.Log.Info( "", logFrom, true, @@ -45,7 +42,7 @@ func ServiceTest( // Check service exists. if !util.Contains(cfg.Order, *flag) { - log.Fatal( + logutil.Log.Fatal( fmt.Sprintf( "Service %q could not be found in config.service\nDid you mean one of these?\n - %s", *flag, strings.Join(cfg.Order, "\n - "), @@ -61,7 +58,7 @@ func ServiceTest( // LatestVersion. _, err := service.LatestVersion.Query(false, logFrom) if err != nil { - log.Error( + logutil.Log.Error( fmt.Sprintf( "No version matching the conditions specified could be found for %q at %q", *flag, @@ -75,7 +72,7 @@ func ServiceTest( // DeployedVersionLookup. if service.DeployedVersionLookup != nil { version, err := service.DeployedVersionLookup.Query(false, logFrom) - log.Info( + logutil.Log.Info( fmt.Sprintf( "Deployed version - %q", version, @@ -85,7 +82,7 @@ func ServiceTest( ) } - if !log.Testing { + if !logutil.Log.Testing { os.Exit(0) } } diff --git a/testing/service_test.go b/testing/service_test.go index 9309bd09..92924952 100644 --- a/testing/service_test.go +++ b/testing/service_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -216,7 +216,7 @@ func TestServiceTest(t *testing.T) { Service: tc.slice, Order: order, } - ServiceTest(&tc.flag, &cfg, jLog) + ServiceTest(&tc.flag, &cfg) // THEN we get the expected stdout stdout := releaseStdout() diff --git a/testing/shoutrrr.go b/testing/shoutrrr.go index abd635b8..e8dda88a 100644 --- a/testing/shoutrrr.go +++ b/testing/shoutrrr.go @@ -25,23 +25,19 @@ import ( "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // NotifyTest will send a test Shoutrrr message to the Shoutrrr with this flag as its ID. -func NotifyTest( - flag *string, - cfg *config.Config, - log *util.JLog, -) { +func NotifyTest(flag *string, cfg *config.Config) { // Only if flag provided. if *flag == "" { return } - shoutrrr.LogInit(log) - logFrom := util.LogFrom{Primary: "Testing", Secondary: *flag} + logFrom := logutil.LogFrom{Primary: "Testing", Secondary: *flag} // Find the Shoutrrr to test. - notify := findShoutrrr(*flag, cfg, log, logFrom) + notify := findShoutrrr(*flag, cfg, logFrom) // Default webURL if not set. if notify.ServiceStatus.WebURL == nil { @@ -51,20 +47,20 @@ func NotifyTest( err := notify.TestSend("https://example.com/service_url") if err == nil { - log.Info( + logutil.Log.Info( fmt.Sprintf("Message sent successfully with %q config\n", *flag), logFrom, true) } else { - log.Fatal( + logutil.Log.Fatal( fmt.Sprintf("Message failed to send with %q config\n%s\n", *flag, err), logFrom, true) } - if !log.Testing { + if !logutil.Log.Testing { os.Exit(0) } } @@ -73,8 +69,7 @@ func NotifyTest( func findShoutrrr( name string, cfg *config.Config, - log *util.JLog, - logFrom util.LogFrom, + logFrom logutil.LogFrom, ) (notify *shoutrrr.Shoutrrr) { // Find in Service.X.Notify.name. for _, svc := range cfg.Service { @@ -122,7 +117,7 @@ func findShoutrrr( if err := notify.CheckValues(" "); err != nil { msg := fmt.Sprintf("notify:\n %s:\n%s\n", name, err) - log.Fatal(msg, logFrom, true) + logutil.Log.Fatal(msg, logFrom, true) } // Not found. @@ -130,7 +125,7 @@ func findShoutrrr( all := getAllShoutrrrNames(cfg) msg := fmt.Sprintf("Notifier %q could not be found in config.notify or in any config.service\nDid you mean one of these?\n - %s\n", name, strings.Join(all, "\n - ")) - log.Fatal(msg, logFrom, true) + logutil.Log.Fatal(msg, logFrom, true) } } serviceID := "TESTING" diff --git a/testing/shoutrrr_test.go b/testing/shoutrrr_test.go index 1c3afa4b..4ed609fa 100644 --- a/testing/shoutrrr_test.go +++ b/testing/shoutrrr_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import ( "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -412,7 +413,7 @@ func TestFindShoutrrr(t *testing.T) { } // WHEN findShoutrrr is called with the test Config - got := findShoutrrr(tc.flag, tc.cfg, jLog, util.LogFrom{}) + got := findShoutrrr(tc.flag, tc.cfg, logutil.LogFrom{}) // THEN we get the expected stdout stdout := releaseStdout() @@ -597,7 +598,7 @@ func TestNotifyTest(t *testing.T) { cfg := config.Config{ Service: tc.slice, Notify: tc.rootSlice} - NotifyTest(&tc.flag, &cfg, jLog) + NotifyTest(&tc.flag, &cfg) // THEN we get the expected stdout stdout := releaseStdout() diff --git a/util/log.go b/util/log/log.go similarity index 90% rename from util/log.go rename to util/log/log.go index 1779cdbe..d7910e3a 100644 --- a/util/log.go +++ b/util/log/log.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package util provides utility functions for the Argus project. -package util +// Package logutil provides a logger. +package logutil import ( "fmt" @@ -21,8 +21,24 @@ import ( "os" "strings" "sync" + + "github.com/release-argus/Argus/util" ) +var ( + Log *JLog + once sync.Once +) + +// Init initialises the logging system with the specified log level. +// The log level determines the severity of the messages that will be logged. +// Valid log levels are "debug", "verbose", "info", "warn" and "error". +func Init(level string, timestamps bool) { + once.Do(func() { + Log = NewJLog(level, timestamps) + }) +} + var ( levelMap = map[string]uint8{ "ERROR": 0, @@ -187,7 +203,7 @@ func (l *JLog) Verbose(msg interface{}, from LogFrom, otherCondition bool) { // VERBOSE: msg from.Primary (from.Secondary) l.logMessage( - TruncateMessage( + util.TruncateMessage( fmt.Sprintf("VERBOSE: %s%v", from, msg), 997)) } @@ -202,7 +218,7 @@ func (l *JLog) Debug(msg interface{}, from LogFrom, otherCondition bool) { // DEBUG: msg from.Primary (from.Secondary) l.logMessage( - TruncateMessage( + util.TruncateMessage( fmt.Sprintf("DEBUG: %s%v", from, msg), 997)) } @@ -215,11 +231,3 @@ func (l *JLog) logMessage(msg string) { fmt.Println(msg) } } - -// TruncateMessage shortens a message to `maxLength` and appends "..." if it exceeds the limit. -func TruncateMessage(msg string, maxLength int) string { - if len(msg) > maxLength { - return msg[:maxLength] + "..." - } - return msg -} diff --git a/util/log_test.go b/util/log/log_test.go similarity index 94% rename from util/log_test.go rename to util/log/log_test.go index a4f2cf54..3757c5ea 100644 --- a/util/log_test.go +++ b/util/log/log_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ //go:build unit -package util +package logutil import ( "bytes" @@ -22,11 +22,55 @@ import ( "fmt" "log" "strings" + "sync" "testing" "github.com/release-argus/Argus/test" + "github.com/release-argus/Argus/util" ) +func TestInit(t *testing.T) { + // GIVEN a log level and timestamps setting + tests := map[string]struct { + level string + timestamps bool + }{ + "INFO and timestamps": { + level: "INFO", timestamps: true}, + "DEBUG, no timestamps": { + level: "DEBUG", timestamps: false}, + "ERROR and timestamps": { + level: "ERROR", timestamps: true}, + "WARN, no timestamps": { + level: "WARN", timestamps: false}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // t.Parallel() - Cannot run in parallel because of the once variable. + // Reset the once variable and Log for each test + once = sync.Once{} + Log = nil + + // WHEN Init is called + Init(tc.level, tc.timestamps) + + // THEN the Log should be initialized correctly + if Log == nil { + t.Fatalf("Log was not initialized") + } + if Log.Level != levelMap[tc.level] { + t.Errorf("want level=%d\ngot level=%d", + levelMap[tc.level], Log.Level) + } + if Log.Timestamps != tc.timestamps { + t.Errorf("want timestamps=%t\ngot timestamps=%t", + tc.timestamps, Log.Timestamps) + } + }) + } +} + func TestNewJLog(t *testing.T) { // GIVEN a new JLog is wanted tests := map[string]struct { @@ -97,7 +141,7 @@ func TestSetLevel(t *testing.T) { r := recover() rStr := fmt.Sprint(r) - if !RegexCheck(*tc.panicRegex, rStr) { + if !util.RegexCheck(*tc.panicRegex, rStr) { t.Errorf("expected a panic that matched %q\ngot: %q", *tc.panicRegex, rStr) } @@ -325,7 +369,7 @@ func TestJLog_Error(t *testing.T) { } else { regex = fmt.Sprintf("^ERROR: %s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("ERROR printed didn't match %q\nGot %q", regex, stdout) } @@ -397,7 +441,7 @@ func TestJLog_Warn(t *testing.T) { } else { regex = fmt.Sprintf("^WARNING: %s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("WARNING printed didn't match %q\nGot %q", regex, stdout) } @@ -469,7 +513,7 @@ func TestJLog_Info(t *testing.T) { } else { regex = fmt.Sprintf("^INFO: %s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("INFO printed didn't match %q\nGot %q", regex, stdout) } @@ -554,7 +598,7 @@ func TestJLog_Verbose(t *testing.T) { } else { regex = fmt.Sprintf("^VERBOSE: %s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("VERBOSE printed didn't match %q\nGot %q", regex, stdout) } @@ -646,7 +690,7 @@ func TestJLog_Debug(t *testing.T) { } else { regex = fmt.Sprintf("^DEBUG: %s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("DEBUG printed didn't match %q\nGot %q", regex, stdout) } @@ -721,7 +765,7 @@ func TestJLog_Fatal(t *testing.T) { stdout = logOut.String() regex = fmt.Sprintf("^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} ERROR: %s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("ERROR wasn't printed/didn't match %q\nGot %q", regex, stdout) } @@ -734,7 +778,7 @@ func TestJLog_Fatal(t *testing.T) { // THEN msg was logged if shouldPrint, with/without timestamps stdout := releaseStdout() regex := "^$" - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("ERROR printed didn't match %q\nGot %q", regex, stdout) } @@ -742,56 +786,6 @@ func TestJLog_Fatal(t *testing.T) { } } -func TestTruncateMessage(t *testing.T) { - // GIVEN a message and a maxLength to adhere to - tests := map[string]struct { - msg string - maxLength int - want string - }{ - "message shorter than maxLength": { - msg: "short message", - maxLength: 20, - want: "short message", - }, - "message equal to maxLength": { - msg: "exact length msg", - maxLength: 16, - want: "exact length msg", - }, - "message longer than maxLength": { - msg: "is this message too long", - maxLength: 10, - want: "is this me...", - }, - "empty message": { - msg: "", - maxLength: 10, - want: "", - }, - "maxLength zero": { - msg: "message", - maxLength: 0, - want: "...", - }, - } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - t.Parallel() - - // WHEN TruncateMessage is called - got := TruncateMessage(tc.msg, tc.maxLength) - - // THEN the message is truncated only if it exceeds maxLength - if got != tc.want { - t.Errorf("truncateMessage(%q, %d) = %q; want %q", - tc.msg, tc.maxLength, got, tc.want) - } - }) - } -} - func TestJLog_logMessage(t *testing.T) { // GIVEN a JLog and a message msg := "test message" @@ -827,7 +821,7 @@ func TestJLog_logMessage(t *testing.T) { regex = fmt.Sprintf("^%s\n$", msg) } - if !RegexCheck(regex, stdout) { + if !util.RegexCheck(regex, stdout) { t.Errorf("logMessage printed didn't match\n%q\ngot:\n%q", regex, stdout) } diff --git a/util/util.go b/util/util.go index 0e5b294e..38b7256d 100644 --- a/util/util.go +++ b/util/util.go @@ -153,3 +153,11 @@ func Indentation(line string, indentSize uint8) string { return strings.Repeat(indent, count) } + +// TruncateMessage shortens a message to `maxLength` and appends "..." if it exceeds the limit. +func TruncateMessage(msg string, maxLength int) string { + if len(msg) > maxLength { + return msg[:maxLength] + "..." + } + return msg +} diff --git a/util/util_test.go b/util/util_test.go index f8788055..5639f898 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -492,3 +492,53 @@ func TestGetIndentation(t *testing.T) { }) } } + +func TestTruncateMessage(t *testing.T) { + // GIVEN a message and a maxLength to adhere to + tests := map[string]struct { + msg string + maxLength int + want string + }{ + "message shorter than maxLength": { + msg: "short message", + maxLength: 20, + want: "short message", + }, + "message equal to maxLength": { + msg: "exact length msg", + maxLength: 16, + want: "exact length msg", + }, + "message longer than maxLength": { + msg: "is this message too long", + maxLength: 10, + want: "is this me...", + }, + "empty message": { + msg: "", + maxLength: 10, + want: "", + }, + "maxLength zero": { + msg: "message", + maxLength: 0, + want: "...", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() + + // WHEN TruncateMessage is called + got := TruncateMessage(tc.msg, tc.maxLength) + + // THEN the message is truncated only if it exceeds maxLength + if got != tc.want { + t.Errorf("truncateMessage(%q, %d) = %q; want %q", + tc.msg, tc.maxLength, got, tc.want) + } + }) + } +} diff --git a/web/api/v1/api.go b/web/api/v1/api.go index cd0e2503..536b5dde 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -22,8 +22,9 @@ import ( "strings" "github.com/gorilla/mux" + "github.com/release-argus/Argus/config" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) @@ -36,9 +37,7 @@ type API struct { } // NewAPI will create a new API with the provided config. -func NewAPI(cfg *config.Config, log *util.JLog) *API { - LogInit(log) - +func NewAPI(cfg *config.Config) *API { baseRouter := mux.NewRouter().StrictSlash(true) routePrefix := cfg.Settings.WebRoutePrefix() @@ -69,14 +68,14 @@ func NewAPI(cfg *config.Config, log *util.JLog) *API { return api } -func (api *API) writeJSON(w http.ResponseWriter, v interface{}, logFrom util.LogFrom) { +func (api *API) writeJSON(w http.ResponseWriter, v interface{}, logFrom logutil.LogFrom) { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("X-Content-Type-Options", "nosniff") if err := json.NewEncoder(w).Encode(v); err != nil { // Encoding error, 500. w.WriteHeader(http.StatusInternalServerError) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) api.writeJSON(w, apitype.Response{ Error: err.Error(), diff --git a/web/api/v1/api_test.go b/web/api/v1/api_test.go index 59d3833c..26d00141 100644 --- a/web/api/v1/api_test.go +++ b/web/api/v1/api_test.go @@ -25,6 +25,7 @@ import ( "github.com/release-argus/Argus/config" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestNewAPI(t *testing.T) { @@ -80,7 +81,7 @@ func TestNewAPI(t *testing.T) { tc.routePrefix = strings.TrimSuffix(tc.routePrefix, "/") // WHEN a new API is created - api := NewAPI(cfg, nil) + api := NewAPI(cfg) // THEN the healthcheck endpoint is accessible req, _ := http.NewRequest("GET", tc.routePrefix+"/api/v1/healthcheck", nil) @@ -176,7 +177,7 @@ func TestWriteJSON(t *testing.T) { api := &API{} // WHEN writeJSON is called with this input. - api.writeJSON(w, tc.input, util.LogFrom{}) + api.writeJSON(w, tc.input, logutil.LogFrom{}) // THEN the status code is as expected. if w.Code != tc.statusCode { diff --git a/web/api/v1/counts.go b/web/api/v1/counts.go index c3e58e9d..13ad8bb2 100644 --- a/web/api/v1/counts.go +++ b/web/api/v1/counts.go @@ -20,7 +20,8 @@ import ( "github.com/prometheus/client_golang/prometheus" promclient "github.com/prometheus/client_model/go" - "github.com/release-argus/Argus/util" + + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web/metric" ) @@ -31,7 +32,7 @@ type CountsResponse struct { } func (api *API) httpCounts(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceSummary", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceSummary", Secondary: getIP(r)} resp := CountsResponse{} diff --git a/web/api/v1/counts_test.go b/web/api/v1/counts_test.go index 466c0117..3e4e3246 100644 --- a/web/api/v1/counts_test.go +++ b/web/api/v1/counts_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/gorilla/mux" + "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/web/metric" ) diff --git a/web/api/v1/help_test.go b/web/api/v1/help_test.go index 8157bb20..b7a9d920 100644 --- a/web/api/v1/help_test.go +++ b/web/api/v1/help_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/gorilla/websocket" + "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/config" dbtype "github.com/release-argus/Argus/db/types" @@ -33,6 +34,7 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -44,15 +46,14 @@ var ( func TestMain(m *testing.M) { // initialise jLog - masterJLog := util.NewJLog("DEBUG", false) - masterJLog.Testing = true + logutil.Init("DEBUG", false) + logutil.Log.Testing = true flags := make(map[string]bool) path := "TestWebAPIv1Main.yml" testYAML_Argus(path) var config config.Config - config.Load(path, &flags, masterJLog) + config.Load(path, &flags) os.Remove(path) - LogInit(masterJLog) // Marshal the secret value '' -> '\u003csecret\u003e' secretValueMarshalledBytes, _ := json.Marshal(util.SecretValue) @@ -79,8 +80,8 @@ func testLoad(file string) *config.Config { var config config.Config flags := make(map[string]bool) - config.Load(file, &flags, nil) - config.Init(false) + config.Load(file, &flags) + config.Init() announceChannel := make(chan []byte, 8) config.HardDefaults.Service.Status.AnnounceChannel = &announceChannel diff --git a/web/api/v1/http-api-action.go b/web/api/v1/http-api-action.go index 753b5767..650c2c81 100644 --- a/web/api/v1/http-api-action.go +++ b/web/api/v1/http-api-action.go @@ -23,7 +23,8 @@ import ( "strings" "github.com/gorilla/mux" - "github.com/release-argus/Argus/util" + + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) @@ -33,7 +34,7 @@ import ( // // service_id: The ID of the Service to get the actions of. func (api *API) httpServiceGetActions(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceActions", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceActions", Secondary: getIP(r)} // Service to get actions of. targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) @@ -42,7 +43,7 @@ func (api *API) httpServiceGetActions(w http.ResponseWriter, r *http.Request) { defer api.Config.OrderMutex.RUnlock() if svc == nil { err := fmt.Sprintf("service %q not found", targetService) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err, http.StatusNotFound) return } @@ -90,7 +91,7 @@ type RunActionsPayload struct { // "webhook_": Approve a specific WebHook. // "command_": Approve a specific Command. func (api *API) httpServiceRunActions(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceRunActions", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceRunActions", Secondary: getIP(r)} // Service to run actions of. targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) @@ -100,7 +101,7 @@ func (api *API) httpServiceRunActions(w http.ResponseWriter, r *http.Request) { defer api.Config.OrderMutex.RUnlock() if svc == nil { err := fmt.Sprintf("service %q not found", targetService) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err, http.StatusNotFound) return } @@ -110,7 +111,7 @@ func (api *API) httpServiceRunActions(w http.ResponseWriter, r *http.Request) { var payload RunActionsPayload err := json.NewDecoder(payloadBytes).Decode(&payload) if err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("Invalid payload - %s", err), logFrom, true) failRequest(&w, "invalid payload", http.StatusBadRequest) @@ -118,13 +119,13 @@ func (api *API) httpServiceRunActions(w http.ResponseWriter, r *http.Request) { } if payload.Target == "" { errMsg := "invalid payload, target service not provided" - jLog.Error(errMsg, logFrom, true) + logutil.Log.Error(errMsg, logFrom, true) failRequest(&w, errMsg, http.StatusBadRequest) return } if !svc.Options.GetActive() { errMsg := "service is inactive, actions can't be run for it" - jLog.Error(errMsg, logFrom, true) + logutil.Log.Error(errMsg, logFrom, true) failRequest(&w, errMsg, http.StatusBadRequest) return } @@ -133,13 +134,13 @@ func (api *API) httpServiceRunActions(w http.ResponseWriter, r *http.Request) { if payload.Target == "ARGUS_SKIP" { msg := fmt.Sprintf("%q release skip - %q", targetService, svc.Status.LatestVersion()) - jLog.Info(msg, logFrom, true) + logutil.Log.Info(msg, logFrom, true) svc.HandleSkip() return } if svc.WebHook == nil && svc.Command == nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("%q does not have any commands/webhooks to approve", targetService), logFrom, true) return @@ -156,7 +157,7 @@ func (api *API) httpServiceRunActions(w http.ResponseWriter, r *http.Request) { "ARGUS_FAILED", "ALL UNSENT/FAILED"), "ARGUS_SKIP", "SKIP"), ) - jLog.Info(msg, logFrom, true) + logutil.Log.Info(msg, logFrom, true) switch payload.Target { case "ARGUS_ALL", "ARGUS_FAILED": go svc.HandleFailedActions() diff --git a/web/api/v1/http-api-action_test.go b/web/api/v1/http-api-action_test.go index 06647586..5e5ad3de 100644 --- a/web/api/v1/http-api-action_test.go +++ b/web/api/v1/http-api-action_test.go @@ -30,6 +30,7 @@ import ( "time" "github.com/gorilla/mux" + "github.com/release-argus/Argus/command" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" diff --git a/web/api/v1/http-api-config.go b/web/api/v1/http-api-config.go index ddd128ab..8692f453 100644 --- a/web/api/v1/http-api-config.go +++ b/web/api/v1/http-api-config.go @@ -19,12 +19,13 @@ import ( "net/http" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) // wsConfig handles getting the config in use and sending it as YAML. func (api *API) httpConfig(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpConfig", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpConfig", Secondary: getIP(r)} cfg := &apitype.Config{} diff --git a/web/api/v1/http-api-edit.go b/web/api/v1/http-api-edit.go index 1c1eebb8..34b533f7 100644 --- a/web/api/v1/http-api-edit.go +++ b/web/api/v1/http-api-edit.go @@ -26,6 +26,7 @@ import ( "time" "github.com/gorilla/mux" + "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service" deployedver "github.com/release-argus/Argus/service/deployed_version" @@ -33,6 +34,7 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) @@ -50,7 +52,7 @@ import ( // On success: JSON object containing the refreshed version and the current UTC datetime. // On error: HTTP 400 Bad Request with an error message. func (api *API) httpLatestVersionRefreshUncreated(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpVersionRefreshUncreated_Latest", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpVersionRefreshUncreated_Latest", Secondary: getIP(r)} queryParams := r.URL.Query() overrides := util.DereferenceOrDefault(getParam(&queryParams, "overrides")) @@ -58,7 +60,7 @@ func (api *API) httpLatestVersionRefreshUncreated(w http.ResponseWriter, r *http // Verify overrides are provided. if overrides == "" { err := errors.New("overrides: ") - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -87,7 +89,7 @@ func (api *API) httpLatestVersionRefreshUncreated(w http.ResponseWriter, r *http "json", overrides, &temp); err != nil { err = fmt.Errorf("invalid JSON: %w", err) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -107,7 +109,7 @@ func (api *API) httpLatestVersionRefreshUncreated(w http.ResponseWriter, r *http } // Error creating/validating the LatestVersionLookup. if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -142,7 +144,7 @@ func (api *API) httpLatestVersionRefreshUncreated(w http.ResponseWriter, r *http // On success: JSON object containing the refreshed version and the current UTC datetime. // On error: HTTP 400 Bad Request with an error message. func (api *API) httpDeployedVersionRefreshUncreated(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpVersionRefreshUncreated_Deployed", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpVersionRefreshUncreated_Deployed", Secondary: getIP(r)} queryParams := r.URL.Query() overrides := util.DereferenceOrDefault(getParam(&queryParams, "overrides")) @@ -150,7 +152,7 @@ func (api *API) httpDeployedVersionRefreshUncreated(w http.ResponseWriter, r *ht // Verify overrides are provided. if overrides == "" { err := errors.New("overrides: ") - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -184,7 +186,7 @@ func (api *API) httpDeployedVersionRefreshUncreated(w http.ResponseWriter, r *ht } // Error creating/validating the DeployedVersionLookup. if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -223,7 +225,7 @@ func (api *API) httpDeployedVersionRefreshUncreated(w http.ResponseWriter, r *ht // On success: JSON object containing the refreshed version and the current UTC datetime. // On error: HTTP 400 Bad Request with an error message. func (api *API) httpLatestVersionRefresh(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpVersionRefresh_Latest", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpVersionRefresh_Latest", Secondary: getIP(r)} // Service to refresh. targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) @@ -234,7 +236,7 @@ func (api *API) httpLatestVersionRefresh(w http.ResponseWriter, r *http.Request) defer api.Config.OrderMutex.RUnlock() if api.Config.Service[targetService] == nil { err := fmt.Sprintf("service %q not found", targetService) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err, http.StatusNotFound) return } @@ -283,7 +285,7 @@ func (api *API) httpLatestVersionRefresh(w http.ResponseWriter, r *http.Request) // On success: JSON object containing the refreshed version and the current UTC datetime. // On error: HTTP 400 Bad Request with an error message. func (api *API) httpDeployedVersionRefresh(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpVersionRefresh_Deployed", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpVersionRefresh_Deployed", Secondary: getIP(r)} // Service to refresh. targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) @@ -294,7 +296,7 @@ func (api *API) httpDeployedVersionRefresh(w http.ResponseWriter, r *http.Reques defer api.Config.OrderMutex.RUnlock() if api.Config.Service[targetService] == nil { err := fmt.Sprintf("service %q not found", targetService) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err, http.StatusNotFound) return } @@ -326,7 +328,7 @@ func (api *API) httpDeployedVersionRefresh(w http.ResponseWriter, r *http.Reques err = dvl.CheckValues("") } if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -363,7 +365,7 @@ func (api *API) httpDeployedVersionRefresh(w http.ResponseWriter, r *http.Reques // // JSON object containing the service details. func (api *API) httpServiceDetail(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceDetail", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceDetail", Secondary: getIP(r)} // Service to get details of. targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) @@ -376,7 +378,7 @@ func (api *API) httpServiceDetail(w http.ResponseWriter, r *http.Request) { if svc == nil { err := fmt.Sprintf("service %q not found", targetService) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err, http.StatusNotFound) return } @@ -406,7 +408,7 @@ func (api *API) httpServiceDetail(w http.ResponseWriter, r *http.Request) { // // JSON object containing the global details. func (api *API) httpOtherServiceDetails(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpOtherServiceDetails", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpOtherServiceDetails", Secondary: getIP(r)} // Convert to JSON type that swaps slices for lists. api.writeJSON(w, @@ -436,7 +438,7 @@ func (api *API) httpOtherServiceDetails(w http.ResponseWriter, r *http.Request) // On success: HTTP 200 OK // On error: HTTP 400 Bad Request with an error message. func (api *API) httpServiceEdit(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceEdit", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceEdit", Secondary: getIP(r)} api.Config.OrderMutex.RLock() defer api.Config.OrderMutex.RUnlock() @@ -478,7 +480,7 @@ func (api *API) httpServiceEdit(w http.ResponseWriter, r *http.Request) { &api.Config.HardDefaults.WebHook, logFrom) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, fmt.Sprintf(`%s %q failed (invalid json)\n%s`, reqType, targetService, err), @@ -499,7 +501,7 @@ func (api *API) httpServiceEdit(w http.ResponseWriter, r *http.Request) { // Check the values. if err := newService.CheckValues(""); err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, fmt.Sprintf(`%s %q failed (invalid values)\n%s`, @@ -510,7 +512,7 @@ func (api *API) httpServiceEdit(w http.ResponseWriter, r *http.Request) { // Ensure LatestVersion and DeployedVersion (if set) can fetch. if err := newService.CheckFetches(); err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, fmt.Sprintf(`%s %q failed (fetches failed)\n%s`, @@ -561,7 +563,7 @@ func (api *API) httpServiceEdit(w http.ResponseWriter, r *http.Request) { // On success: HTTP 200 OK // On error: HTTP 400 Bad Request with an error message. func (api *API) httpServiceDelete(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceDelete", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceDelete", Secondary: getIP(r)} // Service to delete. targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) @@ -603,13 +605,13 @@ func (api *API) httpServiceDelete(w http.ResponseWriter, r *http.Request) { // service_url?: string // web_url?: string func (api *API) httpNotifyTest(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpNotifyTest", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpNotifyTest", Secondary: getIP(r)} // Read payload. payload := http.MaxBytesReader(w, r.Body, 1024_00) var buf bytes.Buffer if _, err := buf.ReadFrom(payload); err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -617,7 +619,7 @@ func (api *API) httpNotifyTest(w http.ResponseWriter, r *http.Request) { var parsedPayload shoutrrr.TestPayload err := json.Unmarshal(buf.Bytes(), &parsedPayload) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -645,7 +647,7 @@ func (api *API) httpNotifyTest(w http.ResponseWriter, r *http.Request) { serviceNotify, api.Config.Notify, api.Config.Defaults.Notify, api.Config.HardDefaults.Notify) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } @@ -656,7 +658,7 @@ func (api *API) httpNotifyTest(w http.ResponseWriter, r *http.Request) { // Send the message. err = testNotify.TestSend(serviceURL) if err != nil { - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err.Error(), http.StatusBadRequest) return } diff --git a/web/api/v1/http-api-edit_test.go b/web/api/v1/http-api-edit_test.go index ab7a0960..8308ebab 100644 --- a/web/api/v1/http-api-edit_test.go +++ b/web/api/v1/http-api-edit_test.go @@ -31,12 +31,14 @@ import ( "time" "github.com/gorilla/mux" + "github.com/release-argus/Argus/notify/shoutrrr" shoutrrr_test "github.com/release-argus/Argus/notify/shoutrrr/test" "github.com/release-argus/Argus/service" "github.com/release-argus/Argus/service/latest_version/types/web" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestHTTP_LatestVersionRefreshUncreated(t *testing.T) { @@ -266,8 +268,8 @@ func TestHTTP_DeployedVersionRefreshUncreated(t *testing.T) { func TestHTTP_LatestVersionRefresh(t *testing.T) { testSVC := testService("TestHTTP_LatestVersionRefresh", false) testSVC.LatestVersion.GetStatus().SetLatestVersion("1.0.0", "", false) - testSVC.LatestVersion.Query(true, util.LogFrom{}) - v, _ := testSVC.DeployedVersionLookup.Query(true, util.LogFrom{}) + testSVC.LatestVersion.Query(true, logutil.LogFrom{}) + v, _ := testSVC.DeployedVersionLookup.Query(true, logutil.LogFrom{}) testSVC.Status.SetDeployedVersion(v, "", false) type wants struct { body string @@ -448,8 +450,8 @@ func TestHTTP_LatestVersionRefresh(t *testing.T) { func TestHTTP_DeployedVersionRefresh(t *testing.T) { testSVC := testService("TestHTTP_DeployedVersionRefresh", false) testSVC.LatestVersion.GetStatus().SetLatestVersion("1.0.0", "", false) - testSVC.LatestVersion.Query(true, util.LogFrom{}) - v, _ := testSVC.DeployedVersionLookup.Query(true, util.LogFrom{}) + testSVC.LatestVersion.Query(true, logutil.LogFrom{}) + v, _ := testSVC.DeployedVersionLookup.Query(true, logutil.LogFrom{}) testSVC.Status.SetDeployedVersion(v, "", false) type wants struct { body string @@ -806,8 +808,8 @@ func TestHTTP_OtherServiceDetails(t *testing.T) { func TestHTTP_ServiceEdit(t *testing.T) { testSVC := testService("TestHTTP_ServiceEdit", true) testSVC.LatestVersion.GetStatus().SetLatestVersion("1.0.0", "", false) - testSVC.LatestVersion.Query(true, util.LogFrom{}) - v, _ := testSVC.DeployedVersionLookup.Query(true, util.LogFrom{}) + testSVC.LatestVersion.Query(true, logutil.LogFrom{}) + v, _ := testSVC.DeployedVersionLookup.Query(true, logutil.LogFrom{}) testSVC.Status.SetDeployedVersion(v, "", false) type wants struct { body string diff --git a/web/api/v1/http-api-flags.go b/web/api/v1/http-api-flags.go index ff160955..c454a12f 100644 --- a/web/api/v1/http-api-flags.go +++ b/web/api/v1/http-api-flags.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,13 +18,13 @@ package v1 import ( "net/http" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) // httpFlags retrieves the values of vars that may get set with flags. func (api *API) httpFlags(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpFlags", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpFlags", Secondary: getIP(r)} // Create and send status page data. msg := apitype.Flags{ diff --git a/web/api/v1/http-api-service.go b/web/api/v1/http-api-service.go index b8433e33..c4dbd76d 100644 --- a/web/api/v1/http-api-service.go +++ b/web/api/v1/http-api-service.go @@ -21,7 +21,8 @@ import ( "net/url" "github.com/gorilla/mux" - "github.com/release-argus/Argus/util" + + logutil "github.com/release-argus/Argus/util/log" ) // ServiceOrderAPI is the API response for the service order. @@ -30,7 +31,7 @@ type ServiceOrderAPI struct { } func (api *API) httpServiceOrder(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceOrder", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceOrder", Secondary: getIP(r)} api.Config.OrderMutex.RLock() defer api.Config.OrderMutex.RUnlock() @@ -38,7 +39,7 @@ func (api *API) httpServiceOrder(w http.ResponseWriter, r *http.Request) { } func (api *API) httpServiceSummary(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpServiceSummary", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpServiceSummary", Secondary: getIP(r)} targetService, _ := url.QueryUnescape(mux.Vars(r)["service_id"]) // Check Service still exists in this ordering. @@ -47,7 +48,7 @@ func (api *API) httpServiceSummary(w http.ResponseWriter, r *http.Request) { service := api.Config.Service[targetService] if service == nil { err := fmt.Sprintf("service %q not found", targetService) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failRequest(&w, err, http.StatusNotFound) return } diff --git a/web/api/v1/http-api-service_test.go b/web/api/v1/http-api-service_test.go index e577cf8c..9b7a550f 100644 --- a/web/api/v1/http-api-service_test.go +++ b/web/api/v1/http-api-service_test.go @@ -28,6 +28,7 @@ import ( "testing" "github.com/gorilla/mux" + "github.com/release-argus/Argus/util" ) diff --git a/web/api/v1/http-api-status.go b/web/api/v1/http-api-status.go index 4613bf5f..801aba71 100644 --- a/web/api/v1/http-api-status.go +++ b/web/api/v1/http-api-status.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,12 +21,13 @@ import ( "runtime" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) // httpRuntimeInfo returns runtime info about the server. func (api *API) httpRuntimeInfo(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpBuildInfo", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpBuildInfo", Secondary: getIP(r)} // Create and send status page data. msg := apitype.RuntimeInfo{ diff --git a/web/api/v1/http.go b/web/api/v1/http.go index dcd0bbde..57efa22a 100644 --- a/web/api/v1/http.go +++ b/web/api/v1/http.go @@ -22,11 +22,13 @@ import ( "strings" "github.com/gorilla/mux" + "github.com/vearutop/statigz" + "github.com/vearutop/statigz/brotli" + "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" "github.com/release-argus/Argus/web/ui" - "github.com/vearutop/statigz" - "github.com/vearutop/statigz/brotli" ) // SetupRoutesAPI will set up the HTTP API routes. @@ -35,7 +37,7 @@ func (api *API) SetupRoutesAPI() { v1Router := api.Router.PathPrefix("/api/v1").Subrouter() // Only if VERBOSE or DEBUG. - if jLog.Level >= 3 { + if logutil.Log.Level >= 3 { // Apply loggerMiddleware to only the /api/v1 routes. v1Router.Use(loggerMiddleware) } @@ -181,7 +183,7 @@ func (api *API) SetupRoutesFavicon() { // httpVersion serves Argus version JSON over HTTP. func (api *API) httpVersion(w http.ResponseWriter, r *http.Request) { - logFrom := util.LogFrom{Primary: "httpVersion", Secondary: getIP(r)} + logFrom := logutil.LogFrom{Primary: "httpVersion", Secondary: getIP(r)} api.writeJSON(w, apitype.VersionAPI{ diff --git a/web/api/v1/http_test.go b/web/api/v1/http_test.go index 129b9eb3..e5fa1c73 100644 --- a/web/api/v1/http_test.go +++ b/web/api/v1/http_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import ( config_test "github.com/release-argus/Argus/config/test" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) @@ -99,7 +100,7 @@ func TestHTTP_BasicAuth(t *testing.T) { if cfg.Settings.Web.BasicAuth != nil { cfg.Settings.Web.BasicAuth.CheckValues() } - api := NewAPI(&cfg, util.NewJLog("WARN", false)) + api := NewAPI(&cfg) api.Router.HandleFunc("/test", func(rw http.ResponseWriter, req *http.Request) { return }) @@ -164,7 +165,7 @@ func TestHTTP_SetupRoutesFavicon(t *testing.T) { cfg := config_test.BareConfig(true) cfg.Settings.Web.Favicon = testFaviconSettings(tc.urlPNG, tc.urlSVG) - api := NewAPI(cfg, util.NewJLog("WARN", false)) + api := NewAPI(cfg) api.SetupRoutesFavicon() ts := httptest.NewServer(api.Router) t.Cleanup(func() { ts.Close() }) @@ -399,8 +400,8 @@ func TestHTTP_DisableRoutes(t *testing.T) { }`, }, } - log := util.NewJLog("WARN", false) - log.Testing = true + logutil.Init("WARN", false) + logutil.Log.Testing = true disableCombinations := test.Combinations(util.SortedKeys(tests)) // Split tests into groups @@ -428,7 +429,7 @@ func TestHTTP_DisableRoutes(t *testing.T) { routePrefix = "/test" cfg.Settings.Web.RoutePrefix = routePrefix } - api := NewAPI(cfg, log) + api := NewAPI(cfg) api.SetupRoutesAPI() ts := httptest.NewServer(api.Router) ts.Config.Handler = api.Router @@ -529,7 +530,7 @@ func TestHTTP_SetupRoutesNodeJS(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { cfg := config_test.BareConfig(true) - api := NewAPI(cfg, util.NewJLog("WARN", false)) + api := NewAPI(cfg) api.SetupRoutesNodeJS() ts := httptest.NewServer(api.Router) t.Cleanup(func() { ts.Close() }) diff --git a/web/api/v1/middleware.go b/web/api/v1/middleware.go index fd10a3f0..f0c6c069 100644 --- a/web/api/v1/middleware.go +++ b/web/api/v1/middleware.go @@ -21,7 +21,8 @@ import ( "net/http" "github.com/gorilla/mux" - "github.com/release-argus/Argus/util" + + logutil "github.com/release-argus/Argus/util/log" ) // basicAuthMiddleware handles basic authentication with hashed credentials. @@ -57,14 +58,14 @@ func (api *API) basicAuthMiddleware() mux.MiddlewareFunc { func loggerMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Log the request. - jLog.Verbose( + logutil.Log.Verbose( fmt.Sprintf( "%s (%s), %s", r.Method, getIP(r), r.URL.Path, ), - util.LogFrom{}, + logutil.LogFrom{}, true) // Process request. diff --git a/web/api/v1/util.go b/web/api/v1/util.go index ff12c1f2..78e2ad7f 100644 --- a/web/api/v1/util.go +++ b/web/api/v1/util.go @@ -19,22 +19,9 @@ import ( "encoding/json" "net/url" - "github.com/release-argus/Argus/util" apitype "github.com/release-argus/Argus/web/api/types" ) -var ( - jLog *util.JLog -) - -// LogInit for this package. -func LogInit(log *util.JLog) { - // Only if unset (avoid RACE condition). - if jLog == nil { - jLog = log - } -} - // getParam from a URL query string. func getParam(queryParams *url.Values, param string) *string { if !queryParams.Has(param) { diff --git a/web/api/v1/websocket-client.go b/web/api/v1/websocket-client.go index 22af7cb8..0e09effa 100644 --- a/web/api/v1/websocket-client.go +++ b/web/api/v1/websocket-client.go @@ -26,7 +26,8 @@ import ( "time" "github.com/gorilla/websocket" - "github.com/release-argus/Argus/util" + + logutil "github.com/release-argus/Argus/util/log" apitype "github.com/release-argus/Argus/web/api/types" ) @@ -125,10 +126,10 @@ func (c *Client) readPump() { defer func() { c.hub.unregister <- c if err := c.conn.Close(); err != nil { - jLog.Verbose( + logutil.Log.Verbose( fmt.Sprintf("Closing the websocket connection failed (readPump)\n%s", err), - util.LogFrom{}, + logutil.LogFrom{}, true) } }() @@ -152,25 +153,25 @@ func (c *Client) readPump() { websocket.CloseGoingAway, websocket.CloseAbnormalClosure, ) { - jLog.Error(err, - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) + logutil.Log.Error(err, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) } break } - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("READ %s", message), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) } message = bytes.TrimSpace(bytes.ReplaceAll(message, newline, space)) // Ensure it meets client message format. var validation serverMessageCheck if err := json.Unmarshal(message, &validation); err != nil || validation.Version != 1 { - jLog.Warn( + logutil.Log.Warn( fmt.Sprintf("Invalid message (missing/invalid version key)\n%s", message), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true, ) continue @@ -189,10 +190,10 @@ func (c *Client) writePump() { defer func() { ticker.Stop() if err := c.conn.Close(); err != nil { - jLog.Verbose( + logutil.Log.Verbose( fmt.Sprintf("Closing the connection\n%s", err), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) } }() @@ -206,10 +207,10 @@ func (c *Client) writePump() { if !ok { // The hub closed the channel. if err := c.conn.WriteMessage(websocket.CloseMessage, []byte{}); err != nil { - jLog.Verbose( + logutil.Log.Verbose( fmt.Sprintf("Closing the connection (writePump)\n%s", err), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) return } @@ -217,10 +218,10 @@ func (c *Client) writePump() { var msg apitype.WebSocketMessage if err := json.Unmarshal(message, &msg); err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("Message failed to unmarshal %s", err), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) continue } @@ -233,16 +234,16 @@ func (c *Client) writePump() { switch msg.Type { case "VERSION", "WEBHOOK", "COMMAND", "SERVICE", "EDIT", "DELETE": if err := c.conn.WriteJSON(msg); err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("Writing JSON to the websocket failed for %s\n%s", msg.Type, err), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) } default: - jLog.Error( + logutil.Log.Error( fmt.Sprintf("Unknown TYPE %q\nFull message: %s", msg.Type, string(message)), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) continue } @@ -252,10 +253,10 @@ func (c *Client) writePump() { n := len(c.send) for i := 0; i < n; i++ { if err := c.conn.WriteJSON(<-c.send); err != nil { - jLog.Error( + logutil.Log.Error( fmt.Sprintf("WriteJSON for the queued chat messages\n%s\n", err), - util.LogFrom{Primary: "WebSocket", Secondary: c.ip}, + logutil.LogFrom{Primary: "WebSocket", Secondary: c.ip}, true) } } diff --git a/web/api/v1/websocket-client_test.go b/web/api/v1/websocket-client_test.go index c100793a..8af1ce78 100644 --- a/web/api/v1/websocket-client_test.go +++ b/web/api/v1/websocket-client_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/gorilla/websocket" + "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" ) @@ -297,7 +298,9 @@ func TestClient_readPump(t *testing.T) { messages: []string{ `{"version":1,"type":"test","page":"home"}`, }, - stdoutRegex: `^$`, + stdoutRegex: test.TrimYAML(` + ^DEBUG:.*READ.* + $`), wantMessages: []string{ `{"version":1,"type":"test","page":"home"}`, }, @@ -305,13 +308,15 @@ func TestClient_readPump(t *testing.T) { "invalid json message": { messages: []string{`{"invalid`}, stdoutRegex: test.TrimYAML(` - ^WARNING:.*Invalid message.* + ^DEBUG:.*READ.* + WARNING:.*Invalid message.* \{"invalid`), }, "message missing version": { messages: []string{`{"type":"test","page":"home"}`}, stdoutRegex: test.TrimYAML(` - ^WARNING:.*Invalid message.* + ^DEBUG:.*READ.* + WARNING:.*Invalid message.* \{.*\}`), }, "connection closed": { diff --git a/web/api/v1/websocket-hub.go b/web/api/v1/websocket-hub.go index 83a1f2c0..fb17bd77 100644 --- a/web/api/v1/websocket-hub.go +++ b/web/api/v1/websocket-hub.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import ( "fmt" "time" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) // Hub maintains the set of active clients and broadcasts messages to those clients. @@ -71,17 +71,17 @@ func (h *Hub) Run() { case message := <-h.Broadcast: n := len(h.Broadcast) + 1 for n != 0 { - if jLog.IsLevel("DEBUG") { - jLog.Debug( + if logutil.Log.IsLevel("DEBUG") { + logutil.Log.Debug( fmt.Sprintf("Broadcast %s", string(message)), - util.LogFrom{Primary: "WebSocket"}, + logutil.LogFrom{Primary: "WebSocket"}, len(h.clients) > 0) } var msg AnnounceMSG if err := json.Unmarshal(message, &msg); err != nil { - jLog.Warn( + logutil.Log.Warn( "Invalid JSON broadcast to the WebSocket", - util.LogFrom{Primary: "WebSocket"}, + logutil.LogFrom{Primary: "WebSocket"}, true, ) n = len(h.Broadcast) diff --git a/web/help_test.go b/web/help_test.go index bbca262b..2b2cf7eb 100644 --- a/web/help_test.go +++ b/web/help_test.go @@ -43,7 +43,7 @@ import ( opt "github.com/release-argus/Argus/service/option" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/webhook" ) @@ -52,13 +52,12 @@ var port string func TestMain(m *testing.M) { // Initialise jLog. - jLog = util.NewJLog("DEBUG", false) - jLog.Testing = true - // v1.LogInit(jLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // GIVEN a valid config with a Service. file := "TestWebMain.yml" - mainCfg = testConfig(file, jLog, nil) + mainCfg = testConfig(file, nil) os.Remove(file) defer os.Remove(mainCfg.Settings.Data.DatabaseFile) port = mainCfg.Settings.Web.ListenPort @@ -66,7 +65,7 @@ func TestMain(m *testing.M) { // WHEN the Router is fetched for this Config. router = newWebUI(mainCfg) - go Run(mainCfg, jLog) + go Run(mainCfg) time.Sleep(250 * time.Millisecond) // THEN Web UI is accessible for the tests. @@ -84,14 +83,14 @@ func getFreePort() (int, error) { return ln.Addr().(*net.TCPAddr).Port, nil } -func testConfig(path string, jLog *util.JLog, t *testing.T) (cfg *config.Config) { +func testConfig(path string, t *testing.T) (cfg *config.Config) { testYAML_Argus(path, t) cfg = &config.Config{} // Settings.Log cfg.Settings.Log.Level = "DEBUG" - cfg.Load(path, &map[string]bool{}, jLog) + cfg.Load(path, &map[string]bool{}) if t != nil { t.Cleanup(func() { os.Remove(cfg.Settings.DataDatabaseFile()) }) } diff --git a/web/web.go b/web/web.go index f397c0b0..41f6d0c6 100644 --- a/web/web.go +++ b/web/web.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,17 +22,16 @@ import ( "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/release-argus/Argus/config" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" v1 "github.com/release-argus/Argus/web/api/v1" ) -var jLog *util.JLog - // NewRouter serves Prometheus metrics, WebSocket, and Node.js frontend at RoutePrefix. func NewRouter(cfg *config.Config, hub *v1.Hub) *mux.Router { // Go - api := v1.NewAPI(cfg, jLog) + api := v1.NewAPI(cfg) // Prometheus metrics api.Router.Handle("/metrics", promhttp.Handler()) @@ -69,16 +68,11 @@ func newWebUI(cfg *config.Config) *mux.Router { } // Run the web server. -func Run(cfg *config.Config, log *util.JLog) { - // Only set if unset (avoid RACE condition in tests). - if log != nil && jLog == nil { - jLog = log - } - +func Run(cfg *config.Config) { router := newWebUI(cfg) listenAddress := fmt.Sprintf("%s:%s", cfg.Settings.WebListenHost(), cfg.Settings.WebListenPort()) - jLog.Info("Listening on "+listenAddress+cfg.Settings.WebRoutePrefix(), util.LogFrom{}, true) + logutil.Log.Info("Listening on "+listenAddress+cfg.Settings.WebRoutePrefix(), logutil.LogFrom{}, true) srv := &http.Server{ Addr: listenAddress, @@ -88,12 +82,12 @@ func Run(cfg *config.Config, log *util.JLog) { } if cfg.Settings.WebCertFile() != "" && cfg.Settings.WebKeyFile() != "" { - jLog.Fatal( + logutil.Log.Fatal( srv.ListenAndServeTLS(cfg.Settings.WebCertFile(), cfg.Settings.WebKeyFile()), - util.LogFrom{}, true) + logutil.LogFrom{}, true) } else { - jLog.Fatal( + logutil.Log.Fatal( srv.ListenAndServe(), - util.LogFrom{}, true) + logutil.LogFrom{}, true) } } diff --git a/web/web_test.go b/web/web_test.go index 0e229915..e336a82f 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import ( "time" "github.com/gorilla/mux" + "github.com/release-argus/Argus/util" ) @@ -32,11 +33,11 @@ var router *mux.Router func TestMainWithRoutePrefix(t *testing.T) { // GIVEN a valid config with a Service - cfg := testConfig("TestMainWithRoutePrefix.yml", nil, t) + cfg := testConfig("TestMainWithRoutePrefix.yml", t) cfg.Settings.Web.RoutePrefix = "/test" // WHEN the Web UI is started with this Config - go Run(cfg, nil) + go Run(cfg) time.Sleep(500 * time.Millisecond) // THEN Web UI is accessible @@ -118,7 +119,7 @@ func TestAccessibleHTTPS(t *testing.T) { bodyRegex: fmt.Sprintf(`"goVersion":"%s"`, util.GoVersion)}, } - cfg := testConfig("TestAccessibleHTTPS.yml", nil, t) + cfg := testConfig("TestAccessibleHTTPS.yml", t) cfg.Settings.Web.CertFile = "TestAccessibleHTTPS_cert.pem" cfg.Settings.Web.KeyFile = "TestAccessibleHTTPS_key.pem" generateCertFiles(cfg.Settings.Web.CertFile, cfg.Settings.Web.KeyFile) @@ -128,7 +129,7 @@ func TestAccessibleHTTPS(t *testing.T) { }) router = newWebUI(cfg) - go Run(cfg, nil) + go Run(cfg) time.Sleep(250 * time.Millisecond) address := fmt.Sprintf("https://localhost:%s", cfg.Settings.Web.ListenPort) diff --git a/webhook/help_test.go b/webhook/help_test.go index ed1283fd..16fa69dd 100644 --- a/webhook/help_test.go +++ b/webhook/help_test.go @@ -21,18 +21,15 @@ import ( "strings" "testing" - "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" - "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" ) func TestMain(m *testing.M) { // initialise jLog - mainJLog := util.NewJLog("DEBUG", false) - mainJLog.Testing = true - LogInit(mainJLog) - shoutrrr.LogInit(mainJLog) + logutil.Init("DEBUG", false) + logutil.Log.Testing = true // run other tests exitCode := m.Run() diff --git a/webhook/init.go b/webhook/init.go index 116e9aad..75a77668 100644 --- a/webhook/init.go +++ b/webhook/init.go @@ -18,15 +18,9 @@ package webhook import ( "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/status" - "github.com/release-argus/Argus/util" "github.com/release-argus/Argus/web/metric" ) -// LogInit for this package. -func LogInit(log *util.JLog) { - jLog = log -} - // Init the Slice metrics and hand out the defaults/notifiers. func (s *Slice) Init( serviceStatus *status.Status, diff --git a/webhook/init_test.go b/webhook/init_test.go index 5ac175b0..b1ae896a 100644 --- a/webhook/init_test.go +++ b/webhook/init_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/test" diff --git a/webhook/send.go b/webhook/send.go index 17611934..83f300e0 100644 --- a/webhook/send.go +++ b/webhook/send.go @@ -27,6 +27,7 @@ import ( "time" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" "github.com/release-argus/Argus/web/metric" ) @@ -63,12 +64,12 @@ func (s *Slice) Send(serviceInfo util.ServiceInfo, useDelay bool) error { // Send the WebHook up to MaxTries times until a success. func (w *WebHook) Send(serviceInfo util.ServiceInfo, useDelay bool) error { - logFrom := util.LogFrom{Primary: w.ID, Secondary: serviceInfo.ID} + logFrom := logutil.LogFrom{Primary: w.ID, Secondary: serviceInfo.ID} if useDelay && w.GetDelay() != "0s" { // Delay sending the WebHook message by the defined interval. msg := fmt.Sprintf("Sleeping for %s before sending the WebHook", w.GetDelay()) - jLog.Info(msg, logFrom, true) + logutil.Log.Info(msg, logFrom, true) w.SetExecuting(true, true) // disable sending of auto_approved w/ delay. time.Sleep(w.GetDelayDuration()) } else { @@ -95,7 +96,7 @@ func (w *WebHook) Send(serviceInfo util.ServiceInfo, useDelay bool) error { err := fmt.Errorf("failed %d times to send the WebHook for %s to %q", w.GetMaxTries(), *w.ServiceStatus.ServiceID, w.ID) - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) failed := true w.Failed.Set(w.ID, &failed) w.AnnounceSend() @@ -109,11 +110,11 @@ func (w *WebHook) Send(serviceInfo util.ServiceInfo, useDelay bool) error { // try sends a WebHook to its URL with the body hashed using SHA1 and SHA256, // encrypted with its Secret, and includes simulated GitHub headers. -func (w *WebHook) try(logFrom util.LogFrom) error { +func (w *WebHook) try(logFrom logutil.LogFrom) error { req := w.BuildRequest() if req == nil { err := fmt.Errorf("failed to get *http.request for WebHook") - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) return err } @@ -143,7 +144,7 @@ func (w *WebHook) try(logFrom util.LogFrom) error { desiredStatusCode := w.GetDesiredStatusCode() if bodyOkay && (resp.StatusCode == int(desiredStatusCode) || (desiredStatusCode == 0 && (strconv.Itoa(resp.StatusCode)[:1] == "2"))) { msg := fmt.Sprintf("(%d) WebHook received", resp.StatusCode) - jLog.Info(msg, logFrom, true) + logutil.Log.Info(msg, logFrom, true) return nil } @@ -194,7 +195,7 @@ func checkWebHookBody(body string) (okay bool) { // parseTry checks the result of a WebHook `try`. // It updates the Prometheus SUCCESS or FAIL counter // and logs any error from the `try`. -func (w *WebHook) parseTry(err error, serviceID string, logFrom util.LogFrom) { +func (w *WebHook) parseTry(err error, serviceID string, logFrom logutil.LogFrom) { // SUCCESS! if err == nil { metric.IncPrometheusCounter(metric.WebHookResultTotal, @@ -209,7 +210,7 @@ func (w *WebHook) parseTry(err error, serviceID string, logFrom util.LogFrom) { } // FAIL! - jLog.Error(err, logFrom, true) + logutil.Log.Error(err, logFrom, true) metric.IncPrometheusCounter(metric.WebHookResultTotal, w.ID, serviceID, diff --git a/webhook/send_test.go b/webhook/send_test.go index 2df00c08..c6c8a032 100644 --- a/webhook/send_test.go +++ b/webhook/send_test.go @@ -26,6 +26,7 @@ import ( shoutrrr_test "github.com/release-argus/Argus/notify/shoutrrr/test" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" + logutil "github.com/release-argus/Argus/util/log" metric "github.com/release-argus/Argus/web/metric" ) @@ -84,7 +85,7 @@ func TestWebHook_Try(t *testing.T) { webhook.DesiredStatusCode = &tc.desiredStatusCode // WHEN try is called on it. - err := webhook.try(util.LogFrom{}) + err := webhook.try(logutil.LogFrom{}) // THEN any err is expected. e := util.ErrorToString(err) diff --git a/webhook/types.go b/webhook/types.go index 7f0d639f..e06cfa31 100644 --- a/webhook/types.go +++ b/webhook/types.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,14 +21,14 @@ import ( "sync" "time" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/service/status" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) var ( - jLog *util.JLog supportedTypes = []string{ "github", "gitlab"} ) diff --git a/webhook/types_test.go b/webhook/types_test.go index b6dc8d8a..0919a7d3 100644 --- a/webhook/types_test.go +++ b/webhook/types_test.go @@ -1,4 +1,4 @@ -// Copyright [2024] [Argus] +// Copyright [2025] [Argus] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,10 +20,11 @@ import ( "strings" "testing" + "gopkg.in/yaml.v3" + "github.com/release-argus/Argus/notify/shoutrrr" "github.com/release-argus/Argus/test" "github.com/release-argus/Argus/util" - "gopkg.in/yaml.v3" ) func TestHeaders_UnmarshalYAML(t *testing.T) {