diff --git a/logger/slog/slog.go b/logger/slog/slog.go index d90daafd..b2260a58 100644 --- a/logger/slog/slog.go +++ b/logger/slog/slog.go @@ -447,6 +447,62 @@ func (s *slogLogger) printLog(ctx context.Context, lvl logger.Level, attrs ...in _ = s.handler.Handle(ctx, r) } +func (s *slogLogger) printLogf(ctx context.Context, lvl logger.Level, format string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() + if !s.V(lvl) { + return + } + + msg := fmt.Sprintf(format, attrs...) + + var nAttrs []interface{} + for _, fn := range s.opts.ContextAttrFuncs { + a := prepareAttributes(fn(ctx)) + nAttrs = append(nAttrs, a...) + } + + hasErr := false + for _, attr := range attrs { + if ve, ok := attr.(error); ok && ve != nil { + hasErr = true + nAttrs = append(nAttrs, slog.String(s.opts.ErrorKey, ve.Error())) + if span, ok := tracer.SpanFromContext(ctx); ok { + span.SetStatus(tracer.SpanStatusError, ve.Error()) + } + break + } + } + + if !hasErr { + for _, attr := range nAttrs { + if ve, ok := attr.(error); ok && ve != nil { + hasErr = true + nAttrs = append(nAttrs, slog.String(s.opts.ErrorKey, ve.Error())) + if span, ok := tracer.SpanFromContext(ctx); ok { + span.SetStatus(tracer.SpanStatusError, ve.Error()) + } + break + } + } + } + + if 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) + if len(traceLines) != 0 { + nAttrs = append(nAttrs, slog.String(s.opts.StacktraceKey, traceLines[len(traceLines)-1])) + } + } + } + + var pcs [1]uintptr + runtime.Callers(defaultCallerSkipCount, pcs[:]) // skip [Callers, printLog, LogLvlMethod] + r := slog.NewRecord(s.opts.TimeFunc(), loggerToSlogLevel(lvl), msg, pcs[0]) + r.Add(nAttrs...) + _ = s.handler.Handle(ctx, r) +} + func NewLogger(opts ...logger.Option) logger.Logger { s := &slogLogger{ opts: logger.NewOptions(opts...),