From d01561365c049fd105cec934f462ecb0163d1a18 Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Sun, 22 Dec 2024 21:53:04 +0300 Subject: [PATCH] logger/slog: write stacktrace on error if enabled, and always on fatal Signed-off-by: Vasiliy Tolstov --- logger/options.go | 3 --- logger/slog/slog.go | 2 +- logger/slog/slog_test.go | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/logger/options.go b/logger/options.go index 4bccf085..85932135 100644 --- a/logger/options.go +++ b/logger/options.go @@ -30,7 +30,6 @@ type Options struct { StacktraceKey string // Name holds the logger name Name string - // Out holds the output writer Out io.Writer // Context holds exernal options @@ -39,12 +38,10 @@ type Options struct { Meter meter.Meter // TimeFunc used to obtain current time TimeFunc func() time.Time - // Fields holds additional metadata Fields []interface{} // ContextAttrFuncs contains funcs that executed before log func on context ContextAttrFuncs []ContextAttrFunc - // callerSkipCount number of frmaes to skip CallerSkipCount int // The logging level the logger should log diff --git a/logger/slog/slog.go b/logger/slog/slog.go index ce8b9d0e..3965efb6 100644 --- a/logger/slog/slog.go +++ b/logger/slog/slog.go @@ -270,7 +270,7 @@ func (s *slogLogger) printLog(ctx context.Context, lvl logger.Level, msg string, } } - if s.opts.AddStacktrace && lvl == logger.ErrorLevel { + if (s.opts.AddStacktrace || lvl == logger.FatalLevel) || (s.opts.AddStacktrace && lvl == logger.ErrorLevel) { stackInfo := make([]byte, 1024*1024) if stackSize := runtime.Stack(stackInfo, false); stackSize > 0 { traceLines := reTrace.Split(string(stackInfo[:stackSize]), -1) diff --git a/logger/slog/slog_test.go b/logger/slog/slog_test.go index 3604dc7f..5032a392 100644 --- a/logger/slog/slog_test.go +++ b/logger/slog/slog_test.go @@ -15,6 +15,24 @@ import ( "go.unistack.org/micro/v3/metadata" ) +func TestStacktrace(t *testing.T) { + ctx := context.TODO() + buf := bytes.NewBuffer(nil) + l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), + WithHandlerFunc(slog.NewTextHandler), + logger.WithAddStacktrace(true), + ) + if err := l.Init(logger.WithFields("key1", "val1")); err != nil { + t.Fatal(err) + } + + l.Error(ctx, "msg1", errors.New("err")) + + if !bytes.Contains(buf.Bytes(), []byte(`slog_test.go:29`)) { + t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) + } +} + func TestWithFields(t *testing.T) { ctx := context.TODO() buf := bytes.NewBuffer(nil)