Commit 32596f3e authored by Sebastian Stammler's avatar Sebastian Stammler Committed by GitHub

log: Fix DynamicLogHandler to also capture derived handlers (#9479)

parent 8cc6aec3
...@@ -12,28 +12,42 @@ type LvlSetter interface { ...@@ -12,28 +12,42 @@ type LvlSetter interface {
// DynamicLogHandler allow runtime-configuration of the log handler. // DynamicLogHandler allow runtime-configuration of the log handler.
type DynamicLogHandler struct { type DynamicLogHandler struct {
slog.Handler // embedded, to expose any extra methods the underlying handler might provide h slog.Handler
minLvl slog.Level minLvl *slog.Level // shared with derived dynamic handlers
} }
func NewDynamicLogHandler(lvl slog.Level, h slog.Handler) *DynamicLogHandler { func NewDynamicLogHandler(lvl slog.Level, h slog.Handler) *DynamicLogHandler {
return &DynamicLogHandler{ return &DynamicLogHandler{
Handler: h, h: h,
minLvl: lvl, minLvl: &lvl,
} }
} }
func (d *DynamicLogHandler) SetLogLevel(lvl slog.Level) { func (d *DynamicLogHandler) SetLogLevel(lvl slog.Level) {
d.minLvl = lvl *d.minLvl = lvl
} }
func (d *DynamicLogHandler) Handle(ctx context.Context, r slog.Record) error { func (d *DynamicLogHandler) Handle(ctx context.Context, r slog.Record) error {
if r.Level < d.minLvl { // higher log level values are more critical if r.Level < *d.minLvl { // higher log level values are more critical
return nil return nil
} }
return d.Handler.Handle(ctx, r) // process the log return d.h.Handle(ctx, r) // process the log
} }
func (d *DynamicLogHandler) Enabled(ctx context.Context, lvl slog.Level) bool { func (d *DynamicLogHandler) Enabled(ctx context.Context, lvl slog.Level) bool {
return (lvl >= d.minLvl) && d.Handler.Enabled(ctx, lvl) return (lvl >= *d.minLvl) && d.h.Enabled(ctx, lvl)
}
func (d *DynamicLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
return &DynamicLogHandler{
h: d.h.WithAttrs(attrs),
minLvl: d.minLvl,
}
}
func (d *DynamicLogHandler) WithGroup(name string) slog.Handler {
return &DynamicLogHandler{
h: d.h.WithGroup(name),
minLvl: d.minLvl,
}
} }
...@@ -40,6 +40,33 @@ func TestDynamicLogHandler_SetLogLevel(t *testing.T) { ...@@ -40,6 +40,33 @@ func TestDynamicLogHandler_SetLogLevel(t *testing.T) {
require.Equal(t, h.records[5].Message, "another error") require.Equal(t, h.records[5].Message, "another error")
} }
func TestDynamicLogHandler_WithAttrs(t *testing.T) {
h := new(testRecorder)
d := NewDynamicLogHandler(log.LevelInfo, h)
logger := log.NewLogger(d)
logwith := logger.With("a", 1) // derived logger
// increase log level
d.SetLogLevel(log.LevelDebug)
logwith.Info("info0") // y
logwith.Debug("debug0") // y
logwith.Trace("trace0") // n
// and decrease log level
d.SetLogLevel(log.LevelWarn)
logwith.Info("info1") // n
logwith.Warn("warn1") // y
logwith.Error("error1") // y
require.Len(t, h.records, 2+2)
require.Equal(t, h.records[0].Message, "info0")
require.Equal(t, h.records[1].Message, "debug0")
require.Equal(t, h.records[2].Message, "warn1")
require.Equal(t, h.records[3].Message, "error1")
}
type testRecorder struct { type testRecorder struct {
records []slog.Record records []slog.Record
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment