diff options
author | Bjørn Erik Pedersen <[email protected]> | 2023-06-16 08:17:42 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2023-06-18 13:03:04 +0200 |
commit | 7c9fada778e91976d4ba1cbe942235a9bbeaf5cb (patch) | |
tree | a717f6e0a5915777ae6859564acd13385213bbab /helpers | |
parent | 0e7944658660b5658b7640dce3cb346d7198d8c9 (diff) | |
download | hugo-7c9fada778e91976d4ba1cbe942235a9bbeaf5cb.tar.gz hugo-7c9fada778e91976d4ba1cbe942235a9bbeaf5cb.zip |
Replace the old log setup, with structured logging etc.
Fixes #11124
Diffstat (limited to 'helpers')
-rw-r--r-- | helpers/general.go | 149 | ||||
-rw-r--r-- | helpers/general_test.go | 56 | ||||
-rw-r--r-- | helpers/testhelpers_test.go | 4 |
3 files changed, 5 insertions, 204 deletions
diff --git a/helpers/general.go b/helpers/general.go index 50f7920f6..d1df2e335 100644 --- a/helpers/general.go +++ b/helpers/general.go @@ -24,13 +24,11 @@ import ( "path/filepath" "sort" "strings" - "sync" "unicode" "unicode/utf8" - "github.com/gohugoio/hugo/common/loggers" - "github.com/gohugoio/hugo/common/hugo" + "github.com/gohugoio/hugo/common/loggers" "github.com/spf13/afero" @@ -254,143 +252,6 @@ func compareStringSlices(a, b []string) bool { return true } -// DistinctLogger ignores duplicate log statements. -type DistinctLogger struct { - loggers.Logger - sync.RWMutex - m map[string]bool -} - -func (l *DistinctLogger) Reset() { - l.Lock() - defer l.Unlock() - - l.m = make(map[string]bool) -} - -// Println will log the string returned from fmt.Sprintln given the arguments, -// but not if it has been logged before. -func (l *DistinctLogger) Println(v ...any) { - // fmt.Sprint doesn't add space between string arguments - logStatement := strings.TrimSpace(fmt.Sprintln(v...)) - l.printIfNotPrinted("println", logStatement, func() { - l.Logger.Println(logStatement) - }) -} - -// Printf will log the string returned from fmt.Sprintf given the arguments, -// but not if it has been logged before. -func (l *DistinctLogger) Printf(format string, v ...any) { - logStatement := fmt.Sprintf(format, v...) - l.printIfNotPrinted("printf", logStatement, func() { - l.Logger.Printf(format, v...) - }) -} - -func (l *DistinctLogger) Debugf(format string, v ...any) { - logStatement := fmt.Sprintf(format, v...) - l.printIfNotPrinted("debugf", logStatement, func() { - l.Logger.Debugf(format, v...) - }) -} - -func (l *DistinctLogger) Debugln(v ...any) { - logStatement := fmt.Sprint(v...) - l.printIfNotPrinted("debugln", logStatement, func() { - l.Logger.Debugln(v...) - }) -} - -func (l *DistinctLogger) Infof(format string, v ...any) { - logStatement := fmt.Sprintf(format, v...) - l.printIfNotPrinted("info", logStatement, func() { - l.Logger.Infof(format, v...) - }) -} - -func (l *DistinctLogger) Infoln(v ...any) { - logStatement := fmt.Sprint(v...) - l.printIfNotPrinted("infoln", logStatement, func() { - l.Logger.Infoln(v...) - }) -} - -func (l *DistinctLogger) Warnf(format string, v ...any) { - logStatement := fmt.Sprintf(format, v...) - l.printIfNotPrinted("warnf", logStatement, func() { - l.Logger.Warnf(format, v...) - }) -} - -func (l *DistinctLogger) Warnln(v ...any) { - logStatement := fmt.Sprint(v...) - l.printIfNotPrinted("warnln", logStatement, func() { - l.Logger.Warnln(v...) - }) -} - -func (l *DistinctLogger) Errorf(format string, v ...any) { - logStatement := fmt.Sprint(v...) - l.printIfNotPrinted("errorf", logStatement, func() { - l.Logger.Errorf(format, v...) - }) -} - -func (l *DistinctLogger) Errorln(v ...any) { - logStatement := fmt.Sprint(v...) - l.printIfNotPrinted("errorln", logStatement, func() { - l.Logger.Errorln(v...) - }) -} - -func (l *DistinctLogger) hasPrinted(key string) bool { - l.RLock() - defer l.RUnlock() - _, found := l.m[key] - return found -} - -func (l *DistinctLogger) printIfNotPrinted(level, logStatement string, print func()) { - key := level + logStatement - if l.hasPrinted(key) { - return - } - l.Lock() - defer l.Unlock() - l.m[key] = true // Placing this after print() can cause duplicate warning entries to be logged when --panicOnWarning is true. - print() - -} - -// NewDistinctErrorLogger creates a new DistinctLogger that logs ERRORs -func NewDistinctErrorLogger() loggers.Logger { - return &DistinctLogger{m: make(map[string]bool), Logger: loggers.NewErrorLogger()} -} - -// NewDistinctLogger creates a new DistinctLogger that logs to the provided logger. -func NewDistinctLogger(logger loggers.Logger) loggers.Logger { - return &DistinctLogger{m: make(map[string]bool), Logger: logger} -} - -// NewDistinctWarnLogger creates a new DistinctLogger that logs WARNs -func NewDistinctWarnLogger() loggers.Logger { - return &DistinctLogger{m: make(map[string]bool), Logger: loggers.NewWarningLogger()} -} - -var ( - // DistinctErrorLog can be used to avoid spamming the logs with errors. - DistinctErrorLog = NewDistinctErrorLogger() - - // DistinctWarnLog can be used to avoid spamming the logs with warnings. - DistinctWarnLog = NewDistinctWarnLogger() -) - -// InitLoggers resets the global distinct loggers. -func InitLoggers() { - DistinctErrorLog.Reset() - DistinctWarnLog.Reset() -} - // Deprecated informs about a deprecation, but only once for a given set of arguments' values. // If the err flag is enabled, it logs as an ERROR (will exit with -1) and the text will // point at the next Hugo release. @@ -398,13 +259,9 @@ func InitLoggers() { // plenty of time to fix their templates. func Deprecated(item, alternative string, err bool) { if err { - DistinctErrorLog.Errorf("%s is deprecated and will be removed in Hugo %s. %s", item, hugo.CurrentVersion.Next().ReleaseVersion(), alternative) + loggers.Log().Errorf("%s is deprecated and will be removed in Hugo %s. %s", item, hugo.CurrentVersion.Next().ReleaseVersion(), alternative) } else { - var warnPanicMessage string - if !loggers.PanicOnWarning.Load() { - warnPanicMessage = "\n\nRe-run Hugo with the flag --panicOnWarning to get a better error message." - } - DistinctWarnLog.Warnf("%s is deprecated and will be removed in a future release. %s%s", item, alternative, warnPanicMessage) + loggers.Log().Warnf("%s is deprecated and will be removed in a future release. %s%s", item, alternative) } } diff --git a/helpers/general_test.go b/helpers/general_test.go index 9b2e4fc58..827411027 100644 --- a/helpers/general_test.go +++ b/helpers/general_test.go @@ -18,9 +18,7 @@ import ( "reflect" "strings" "testing" - "time" - "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/helpers" qt "github.com/frankban/quicktest" @@ -55,60 +53,6 @@ func TestResolveMarkup(t *testing.T) { } } -func TestDistinctLoggerDoesNotLockOnWarningPanic(t *testing.T) { - // Testing to make sure logger mutex doesn't lock if warnings cause panics. - // func Warnf() of DistinctLogger is defined in general.go - l := helpers.NewDistinctLogger(loggers.NewWarningLogger()) - - // Set PanicOnWarning to true to reproduce issue 9380 - // Ensure global variable loggers.PanicOnWarning is reset to old value after test - if !loggers.PanicOnWarning.Load() { - loggers.PanicOnWarning.Store(true) - defer func() { - loggers.PanicOnWarning.Store(false) - }() - } - - // Establish timeout in case a lock occurs: - timeIsUp := make(chan bool) - timeOutSeconds := 1 - go func() { - time.Sleep(time.Second * time.Duration(timeOutSeconds)) - timeIsUp <- true - }() - - // Attempt to run multiple logging threads in parallel - counterC := make(chan int) - goroutines := 5 - - for i := 0; i < goroutines; i++ { - go func() { - defer func() { - // Intentional panic successfully recovered - notify counter channel - recover() - counterC <- 1 - }() - - l.Warnf("Placeholder template message: %v", "In this test, logging a warning causes a panic.") - }() - } - - // All goroutines should complete before timeout - var counter int - for { - select { - case <-counterC: - counter++ - if counter == goroutines { - return - } - case <-timeIsUp: - t.Errorf("Unable to log warnings with --panicOnWarning within alloted time of: %v seconds. Investigate possible mutex locking on panic in distinct warning logger.", timeOutSeconds) - return - } - } -} - func TestFirstUpper(t *testing.T) { for i, this := range []struct { in string diff --git a/helpers/testhelpers_test.go b/helpers/testhelpers_test.go index be8983fdb..6c5f62488 100644 --- a/helpers/testhelpers_test.go +++ b/helpers/testhelpers_test.go @@ -23,7 +23,7 @@ func newTestPathSpecFromCfgAndLang(cfg config.Provider, lang string) *helpers.Pa } } fs := hugofs.NewFrom(mfs, conf.BaseConfig()) - ps, err := helpers.NewPathSpec(fs, conf, loggers.NewErrorLogger()) + ps, err := helpers.NewPathSpec(fs, conf, loggers.NewDefault()) if err != nil { panic(err) } @@ -41,7 +41,7 @@ func newTestPathSpec(configKeyValues ...any) *helpers.PathSpec { func newTestContentSpec(cfg config.Provider) *helpers.ContentSpec { fs := afero.NewMemMapFs() conf := testconfig.GetTestConfig(fs, cfg) - spec, err := helpers.NewContentSpec(conf, loggers.NewErrorLogger(), fs, nil) + spec, err := helpers.NewContentSpec(conf, loggers.NewDefault(), fs, nil) if err != nil { panic(err) } |