logger/slog: fix race condigtion with Enabled and Level
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user