refactor: use slog.LevelVar for dynamic log levels
Replace the pattern of recreating the logger handler when enabling debug logging. Now use slog.LevelVar which allows changing the log level dynamically without recreating the handler or logger instance. closes #8
This commit is contained in:
parent
d4eef6bd6a
commit
3e3d44a168
@ -118,8 +118,6 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
|
||||
if s.Debug {
|
||||
params.Logger.EnableDebugLogging()
|
||||
s.log = params.Logger.Get()
|
||||
log.Debug("Debug mode enabled")
|
||||
}
|
||||
|
||||
// Log configuration summary (without secrets)
|
||||
|
||||
@ -17,8 +17,9 @@ type LoggerParams struct {
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
logger *slog.Logger
|
||||
params LoggerParams
|
||||
logger *slog.Logger
|
||||
levelVar *slog.LevelVar
|
||||
params LoggerParams
|
||||
}
|
||||
|
||||
// nolint:revive // lc parameter is required by fx even if unused
|
||||
@ -26,24 +27,30 @@ func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
|
||||
l := new(Logger)
|
||||
l.params = params
|
||||
|
||||
// Use slog.LevelVar for dynamic log level changes
|
||||
l.levelVar = new(slog.LevelVar)
|
||||
l.levelVar.Set(slog.LevelInfo)
|
||||
|
||||
// Determine if we're running in a terminal
|
||||
tty := false
|
||||
if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) != 0 {
|
||||
tty = true
|
||||
}
|
||||
|
||||
replaceAttr := func(_ []string, a slog.Attr) slog.Attr { // nolint:revive // groups unused
|
||||
// Always use UTC for timestamps
|
||||
if a.Key == slog.TimeKey {
|
||||
if t, ok := a.Value.Any().(time.Time); ok {
|
||||
return slog.Time(slog.TimeKey, t.UTC())
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
var handler slog.Handler
|
||||
opts := &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr { // nolint:revive // groups unused
|
||||
// Always use UTC for timestamps
|
||||
if a.Key == slog.TimeKey {
|
||||
if t, ok := a.Value.Any().(time.Time); ok {
|
||||
return slog.Time(slog.TimeKey, t.UTC())
|
||||
}
|
||||
}
|
||||
return a
|
||||
},
|
||||
Level: l.levelVar,
|
||||
ReplaceAttr: replaceAttr,
|
||||
}
|
||||
|
||||
if tty {
|
||||
@ -63,34 +70,7 @@ func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
|
||||
}
|
||||
|
||||
func (l *Logger) EnableDebugLogging() {
|
||||
// Recreate logger with debug level
|
||||
tty := false
|
||||
if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) != 0 {
|
||||
tty = true
|
||||
}
|
||||
|
||||
var handler slog.Handler
|
||||
opts := &slog.HandlerOptions{
|
||||
Level: slog.LevelDebug,
|
||||
ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr { // nolint:revive // groups unused
|
||||
// Always use UTC for timestamps
|
||||
if a.Key == slog.TimeKey {
|
||||
if t, ok := a.Value.Any().(time.Time); ok {
|
||||
return slog.Time(slog.TimeKey, t.UTC())
|
||||
}
|
||||
}
|
||||
return a
|
||||
},
|
||||
}
|
||||
|
||||
if tty {
|
||||
handler = slog.NewTextHandler(os.Stdout, opts)
|
||||
} else {
|
||||
handler = slog.NewJSONHandler(os.Stdout, opts)
|
||||
}
|
||||
|
||||
l.logger = slog.New(handler)
|
||||
slog.SetDefault(l.logger)
|
||||
l.levelVar.Set(slog.LevelDebug)
|
||||
l.logger.Debug("debug logging enabled", "debug", true)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user