updates #207
| @@ -5,6 +5,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log/slog" | 	"log/slog" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"regexp" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"sync" | 	"sync" | ||||||
| @@ -14,6 +15,8 @@ import ( | |||||||
| 	"go.unistack.org/micro/v3/tracer" | 	"go.unistack.org/micro/v3/tracer" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | var reTrace = regexp.MustCompile(`.*/slog/logger\.go.*\n`) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	DefaultSourceKey  string = slog.SourceKey | 	DefaultSourceKey  string = slog.SourceKey | ||||||
| 	DefaultTimeKey    string = slog.TimeKey | 	DefaultTimeKey    string = slog.TimeKey | ||||||
| @@ -290,6 +293,15 @@ func (s *slogLogger) Error(ctx context.Context, attrs ...interface{}) { | |||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
| 	r := slog.NewRecord(time.Now(), slog.LevelError, fmt.Sprintf("%s", attrs[0]), pcs[0]) | 	r := slog.NewRecord(time.Now(), slog.LevelError, fmt.Sprintf("%s", attrs[0]), pcs[0]) | ||||||
| 	//	r.Add(attrs[1:]...) | 	//	r.Add(attrs[1:]...) | ||||||
|  | 	if s.opts.Stacktrace { | ||||||
|  | 		stackInfo := make([]byte, 1024*1024) | ||||||
|  | 		if stackSize := runtime.Stack(stackInfo, false); stackSize > 0 { | ||||||
|  | 			traceLines := reTrace.Split(string(stackInfo[:stackSize]), -1) | ||||||
|  | 			if len(traceLines) != 0 { | ||||||
|  | 				r.AddAttrs(slog.String("stacktrace", traceLines[len(traceLines)-1])) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	r.Attrs(func(a slog.Attr) bool { | 	r.Attrs(func(a slog.Attr) bool { | ||||||
| 		if a.Key == "error" { | 		if a.Key == "error" { | ||||||
| 			if span, ok := tracer.SpanFromContext(ctx); ok { | 			if span, ok := tracer.SpanFromContext(ctx); ok { | ||||||
| @@ -310,6 +322,15 @@ func (s *slogLogger) Errorf(ctx context.Context, msg string, attrs ...interface{ | |||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
| 	r := slog.NewRecord(time.Now(), slog.LevelError, fmt.Sprintf(msg, attrs...), pcs[0]) | 	r := slog.NewRecord(time.Now(), slog.LevelError, fmt.Sprintf(msg, attrs...), pcs[0]) | ||||||
| 	// r.Add(attrs...) | 	// r.Add(attrs...) | ||||||
|  | 	if s.opts.Stacktrace { | ||||||
|  | 		stackInfo := make([]byte, 1024*1024) | ||||||
|  | 		if stackSize := runtime.Stack(stackInfo, false); stackSize > 0 { | ||||||
|  | 			traceLines := reTrace.Split(string(stackInfo[:stackSize]), -1) | ||||||
|  | 			if len(traceLines) != 0 { | ||||||
|  | 				r.AddAttrs(slog.String("stacktrace", traceLines[len(traceLines)-1])) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	r.Attrs(func(a slog.Attr) bool { | 	r.Attrs(func(a slog.Attr) bool { | ||||||
| 		if a.Key == "error" { | 		if a.Key == "error" { | ||||||
| 			if span, ok := tracer.SpanFromContext(ctx); ok { | 			if span, ok := tracer.SpanFromContext(ctx); ok { | ||||||
|   | |||||||
| @@ -9,6 +9,20 @@ import ( | |||||||
| 	"go.unistack.org/micro/v3/logger" | 	"go.unistack.org/micro/v3/logger" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | func TestError(t *testing.T) { | ||||||
|  | 	ctx := context.TODO() | ||||||
|  | 	buf := bytes.NewBuffer(nil) | ||||||
|  | 	l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), logger.WithStacktrace(true)) | ||||||
|  | 	if err := l.Init(); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	l.Error(ctx, "message") | ||||||
|  | 	if !bytes.Contains(buf.Bytes(), []byte(`"stacktrace":"`)) { | ||||||
|  | 		t.Fatalf("logger stacktrace not works, buf contains: %s", buf.Bytes()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func TestContext(t *testing.T) { | func TestContext(t *testing.T) { | ||||||
| 	ctx := context.TODO() | 	ctx := context.TODO() | ||||||
| 	buf := bytes.NewBuffer(nil) | 	buf := bytes.NewBuffer(nil) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user