logger/slog: fix race condigtion with Enabled and Level

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2024-11-24 23:40:54 +03:00
parent 49055a28ea
commit 43acf44c78

View File

@ -8,6 +8,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"sync" "sync"
"sync/atomic"
"go.unistack.org/micro/v3/logger" "go.unistack.org/micro/v3/logger"
"go.unistack.org/micro/v3/semconv" "go.unistack.org/micro/v3/semconv"
@ -33,12 +34,11 @@ var (
type wrapper struct { type wrapper struct {
h slog.Handler h slog.Handler
level logger.Level level atomic.Int64
} }
func (h *wrapper) Enabled(ctx context.Context, level slog.Level) bool { func (h *wrapper) Enabled(ctx context.Context, level slog.Level) bool {
lvl := slogToLoggerLevel(level) return level >= slog.Level(int(h.level.Load()))
return h.level.Enabled(lvl)
} }
func (h *wrapper) Handle(ctx context.Context, rec slog.Record) error { func (h *wrapper) Handle(ctx context.Context, rec slog.Record) error {
@ -110,20 +110,25 @@ func (s *slogLogger) Clone(opts ...logger.Option) logger.Logger {
attrs, _ := s.argsAttrs(options.Fields) attrs, _ := s.argsAttrs(options.Fields)
l := &slogLogger{ l := &slogLogger{
handler: &wrapper{level: options.Level, h: s.handler.h.WithAttrs(attrs)}, handler: &wrapper{h: s.handler.h.WithAttrs(attrs)},
opts: options, opts: options,
} }
l.handler.level.Store(int64(loggerToSlogLevel(options.Level)))
return l return l
} }
func (s *slogLogger) V(level logger.Level) bool { func (s *slogLogger) V(level logger.Level) bool {
return s.opts.Level.Enabled(level) s.mu.Lock()
v := s.opts.Level.Enabled(level)
s.mu.Unlock()
return v
} }
func (s *slogLogger) Level(level logger.Level) { func (s *slogLogger) Level(level logger.Level) {
s.mu.Lock() s.mu.Lock()
s.opts.Level = level s.opts.Level = level
s.handler.level.Store(int64(loggerToSlogLevel(level)))
s.mu.Unlock() s.mu.Unlock()
} }
@ -143,7 +148,8 @@ func (s *slogLogger) Fields(fields ...interface{}) logger.Logger {
} }
attrs, _ := s.argsAttrs(fields) attrs, _ := s.argsAttrs(fields)
l.handler = &wrapper{level: s.opts.Level, h: s.handler.h.WithAttrs(attrs)} l.handler = &wrapper{h: s.handler.h.WithAttrs(attrs)}
l.handler.level.Store(int64(loggerToSlogLevel(l.opts.Level)))
return l return l
} }
@ -166,7 +172,8 @@ func (s *slogLogger) Init(opts ...logger.Option) error {
} }
attrs, _ := s.argsAttrs(s.opts.Fields) attrs, _ := s.argsAttrs(s.opts.Fields)
s.handler = &wrapper{level: s.opts.Level, h: slog.NewJSONHandler(s.opts.Out, handleOpt).WithAttrs(attrs)} s.handler = &wrapper{h: slog.NewJSONHandler(s.opts.Out, handleOpt).WithAttrs(attrs)}
s.handler.level.Store(int64(loggerToSlogLevel(s.opts.Level)))
s.mu.Unlock() s.mu.Unlock()
return nil return nil