diff --git a/logger/slog/slog.go b/logger/slog/slog.go index 8a4260f1..534675f5 100644 --- a/logger/slog/slog.go +++ b/logger/slog/slog.go @@ -4,6 +4,7 @@ import ( "context" "log/slog" "os" + "reflect" "regexp" "runtime" "strconv" @@ -177,6 +178,16 @@ func (s *slogLogger) Init(opts ...logger.Option) error { if v, ok := s.opts.Context.Value(handlerKey{}).(slog.Handler); ok && v != nil { h = v } + + if fn := s.opts.Context.Value(handlerFnKey{}); fn != nil { + if rfn := reflect.ValueOf(fn); rfn.Kind() == reflect.Func { + if ret := rfn.Call([]reflect.Value{reflect.ValueOf(s.opts.Out), reflect.ValueOf(handleOpt)}); len(ret) == 1 { + if iface, ok := ret[0].Interface().(slog.Handler); ok && iface != nil { + h = iface + } + } + } + } } if h == nil { @@ -347,3 +358,9 @@ type handlerKey struct{} func WithHandler(h slog.Handler) logger.Option { return logger.SetOption(handlerKey{}, h) } + +type handlerFnKey struct{} + +func WithHandlerFunc(fn any) logger.Option { + return logger.SetOption(handlerFnKey{}, fn) +} diff --git a/logger/slog/slog_test.go b/logger/slog/slog_test.go index ba9b69ba..24a60bde 100644 --- a/logger/slog/slog_test.go +++ b/logger/slog/slog_test.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "log" + "log/slog" "strings" "testing" @@ -15,6 +16,23 @@ import ( "go.unistack.org/micro/v3/logger" ) +func TestWithHandlerFunc(t *testing.T) { + ctx := context.TODO() + buf := bytes.NewBuffer(nil) + l := NewLogger(logger.WithLevel(logger.InfoLevel), logger.WithOutput(buf), + WithHandlerFunc(slog.NewTextHandler), + ) + if err := l.Init(); err != nil { + t.Fatal(err) + } + + l.Info(ctx, "msg1") + + if !bytes.Contains(buf.Bytes(), []byte(`msg=msg1`)) { + t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) + } +} + func TestWithAddFields(t *testing.T) { ctx := context.TODO() buf := bytes.NewBuffer(nil)