From bcffe14dc6d84a02c452c8b7431e133ffdd02023 Mon Sep 17 00:00:00 2001 From: David Rogers <120214987+drogers0@users.noreply.github.com> Date: Fri, 7 Aug 2026 11:00:01 -0500 Subject: [PATCH] feat(log): add package-level SetLevel to control default logger verbosity The package-level logger (used by log.Info/Warn/Error and by extraction code throughout the library) could only be made louder, via SetVerbose; there was no way to raise its threshold. Projects embedding HackBrowserData as a library had no supported way to quiet its stderr output. Add SetLevel(v Level), the sibling of SetVerbose, delegating to the default logger's existing SetLevel. Consumers can now call, e.g., log.SetLevel(log.FatalLevel) to silence everything short of a fatal error. SetVerbose is refactored to call SetLevel(DebugLevel); no behavior change for existing callers. --- log/log.go | 11 ++++++++++- log/log_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 log/log_test.go diff --git a/log/log.go b/log/log.go index 38d6d4d7..939b9afa 100644 --- a/log/log.go +++ b/log/log.go @@ -5,8 +5,17 @@ import "fmt" // defaultLogger is the default logger used by the package-level functions. var defaultLogger = NewLogger(nil) +// SetLevel sets the minimum level of the package-level logger; messages below v +// are suppressed. Consumers embedding HackBrowserData as a library use it to +// quiet output, e.g. SetLevel(FatalLevel) to silence everything short of a fatal +// error. It panics if v is less than DebugLevel or greater than FatalLevel. +func SetLevel(v Level) { + defaultLogger.SetLevel(v) +} + +// SetVerbose lowers the package-level logger to DebugLevel. func SetVerbose() { - defaultLogger.SetLevel(DebugLevel) + SetLevel(DebugLevel) } func Debug(args ...any) { diff --git a/log/log_test.go b/log/log_test.go new file mode 100644 index 00000000..ec08a55e --- /dev/null +++ b/log/log_test.go @@ -0,0 +1,25 @@ +package log + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSetLevel(t *testing.T) { + t.Cleanup(func() { SetLevel(InfoLevel) }) // restore package default + + SetLevel(FatalLevel) + assert.False(t, defaultLogger.canLogAt(InfoLevel), "Info must be suppressed at FatalLevel") + assert.False(t, defaultLogger.canLogAt(WarnLevel), "Warn must be suppressed at FatalLevel") + assert.False(t, defaultLogger.canLogAt(ErrorLevel), "Error must be suppressed at FatalLevel") + assert.True(t, defaultLogger.canLogAt(FatalLevel), "Fatal must still log at FatalLevel") + + SetVerbose() + assert.True(t, defaultLogger.canLogAt(DebugLevel), "SetVerbose must enable Debug") +} + +func TestSetLevelInvalidPanics(t *testing.T) { + t.Cleanup(func() { SetLevel(InfoLevel) }) + assert.Panics(t, func() { SetLevel(FatalLevel + 1) }) +}