update slog/logger #351
| @@ -15,7 +15,7 @@ var ( | |||||||
| 	// DefaultLevel used by logger | 	// DefaultLevel used by logger | ||||||
| 	DefaultLevel = InfoLevel | 	DefaultLevel = InfoLevel | ||||||
| 	// DefaultCallerSkipCount used by logger | 	// DefaultCallerSkipCount used by logger | ||||||
| 	DefaultCallerSkipCount = 2 | 	DefaultCallerSkipCount = 3 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Logger is a generic logging interface | // Logger is a generic logging interface | ||||||
|   | |||||||
| @@ -154,6 +154,241 @@ func (s *slogLogger) Init(opts ...logger.Option) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interface{}) { | func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, lvl, attrs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Logf DEPRECATED | ||||||
|  | func (s *slogLogger) Logf(ctx context.Context, lvl logger.Level, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() | ||||||
|  | 	if !s.V(lvl) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), loggerToSlogLevel(lvl), msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, 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 { | ||||||
|  | 				attrs = append(attrs, (slog.String(s.opts.StacktraceKey, traceLines[len(traceLines)-1]))) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs[1:]...) | ||||||
|  | 	r.Attrs(func(a slog.Attr) bool { | ||||||
|  | 		if a.Key == s.opts.ErrorKey { | ||||||
|  | 			if span, ok := tracer.SpanFromContext(ctx); ok { | ||||||
|  | 				span.SetStatus(tracer.SpanStatusError, a.Value.String()) | ||||||
|  | 				return false | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return true | ||||||
|  | 	}) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Info(ctx context.Context, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, logger.InfoLevel, attrs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Infof DEPRECATED | ||||||
|  | func (s *slogLogger) Infof(ctx context.Context, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.InfoLevel.String()).Inc() | ||||||
|  | 	if !s.V(logger.InfoLevel) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelInfo, msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs...) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Debug(ctx context.Context, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, logger.DebugLevel, attrs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Debugf DEPRECATED | ||||||
|  | func (s *slogLogger) Debugf(ctx context.Context, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.DebugLevel.String()).Inc() | ||||||
|  | 	if !s.V(logger.DebugLevel) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelDebug, msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs...) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Trace(ctx context.Context, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, logger.TraceLevel, attrs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Tracef DEPRECATED | ||||||
|  | func (s *slogLogger) Tracef(ctx context.Context, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.TraceLevel.String()).Inc() | ||||||
|  | 	if !s.V(logger.TraceLevel) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelDebug-1, msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs[1:]...) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Error(ctx context.Context, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, logger.ErrorLevel, attrs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Errorf DEPRECATED | ||||||
|  | func (s *slogLogger) Errorf(ctx context.Context, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.ErrorLevel.String()).Inc() | ||||||
|  | 	if !s.V(logger.ErrorLevel) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelError, msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if s.opts.AddStacktrace { | ||||||
|  | 		stackInfo := make([]byte, 1024*1024) | ||||||
|  | 		if stackSize := runtime.Stack(stackInfo, false); stackSize > 0 { | ||||||
|  | 			traceLines := reTrace.Split(string(stackInfo[:stackSize]), -1) | ||||||
|  | 			if len(traceLines) != 0 { | ||||||
|  | 				attrs = append(attrs, slog.String("stacktrace", traceLines[len(traceLines)-1])) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs...) | ||||||
|  | 	r.Attrs(func(a slog.Attr) bool { | ||||||
|  | 		if a.Key == s.opts.ErrorKey { | ||||||
|  | 			if span, ok := tracer.SpanFromContext(ctx); ok { | ||||||
|  | 				span.SetStatus(tracer.SpanStatusError, a.Value.String()) | ||||||
|  | 				return false | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return true | ||||||
|  | 	}) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Fatal(ctx context.Context, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, logger.FatalLevel, attrs...) | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Fatalf DEPRECATED | ||||||
|  | func (s *slogLogger) Fatalf(ctx context.Context, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.FatalLevel.String()).Inc() | ||||||
|  | 	if !s.V(logger.FatalLevel) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelError+1, msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs...) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | 	os.Exit(1) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Warn(ctx context.Context, attrs ...interface{}) { | ||||||
|  | 	s.printLog(ctx, logger.WarnLevel, attrs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Warnf DEPRECATED | ||||||
|  | func (s *slogLogger) Warnf(ctx context.Context, msg string, attrs ...interface{}) { | ||||||
|  | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.WarnLevel.String()).Inc() | ||||||
|  | 	if !s.V(logger.WarnLevel) || len(attrs) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	var pcs [1]uintptr | ||||||
|  | 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] | ||||||
|  | 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelWarn, msg, pcs[0]) | ||||||
|  | 	for _, fn := range s.opts.ContextAttrFuncs { | ||||||
|  | 		attrs = append(attrs, fn(ctx)...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for idx, attr := range attrs { | ||||||
|  | 		if ve, ok := attr.(error); ok && ve != nil { | ||||||
|  | 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.Add(attrs[1:]...) | ||||||
|  | 	_ = s.handler.Handle(ctx, r) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) Name() string { | ||||||
|  | 	return s.opts.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) String() string { | ||||||
|  | 	return "slog" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *slogLogger) printLog(ctx context.Context, lvl logger.Level, attrs ...interface{}) { | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() | 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() | ||||||
| 	if !s.V(lvl) || len(attrs) == 0 { | 	if !s.V(lvl) || len(attrs) == 0 { | ||||||
| 		return | 		return | ||||||
| @@ -205,237 +440,6 @@ func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interfa | |||||||
| 	_ = s.handler.Handle(ctx, r) | 	_ = s.handler.Handle(ctx, r) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Logf DEPRECATED |  | ||||||
| func (s *slogLogger) Logf(ctx context.Context, lvl logger.Level, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() |  | ||||||
| 	if !s.V(lvl) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), loggerToSlogLevel(lvl), msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, 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 { |  | ||||||
| 				attrs = append(attrs, (slog.String(s.opts.StacktraceKey, traceLines[len(traceLines)-1]))) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs[1:]...) |  | ||||||
| 	r.Attrs(func(a slog.Attr) bool { |  | ||||||
| 		if a.Key == s.opts.ErrorKey { |  | ||||||
| 			if span, ok := tracer.SpanFromContext(ctx); ok { |  | ||||||
| 				span.SetStatus(tracer.SpanStatusError, a.Value.String()) |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	}) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Info(ctx context.Context, attrs ...interface{}) { |  | ||||||
| 	s.Log(ctx, logger.InfoLevel, attrs...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Infof DEPRECATED |  | ||||||
| func (s *slogLogger) Infof(ctx context.Context, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.InfoLevel.String()).Inc() |  | ||||||
| 	if !s.V(logger.InfoLevel) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelInfo, msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs...) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Debug(ctx context.Context, attrs ...interface{}) { |  | ||||||
| 	s.Log(ctx, logger.DebugLevel, attrs...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Debugf DEPRECATED |  | ||||||
| func (s *slogLogger) Debugf(ctx context.Context, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.DebugLevel.String()).Inc() |  | ||||||
| 	if !s.V(logger.DebugLevel) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelDebug, msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs...) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Trace(ctx context.Context, attrs ...interface{}) { |  | ||||||
| 	s.Log(ctx, logger.TraceLevel, attrs...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Tracef DEPRECATED |  | ||||||
| func (s *slogLogger) Tracef(ctx context.Context, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.TraceLevel.String()).Inc() |  | ||||||
| 	if !s.V(logger.TraceLevel) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelDebug-1, msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs[1:]...) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Error(ctx context.Context, attrs ...interface{}) { |  | ||||||
| 	s.Log(ctx, logger.ErrorLevel, attrs...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Errorf DEPRECATED |  | ||||||
| func (s *slogLogger) Errorf(ctx context.Context, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.ErrorLevel.String()).Inc() |  | ||||||
| 	if !s.V(logger.ErrorLevel) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelError, msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if s.opts.AddStacktrace { |  | ||||||
| 		stackInfo := make([]byte, 1024*1024) |  | ||||||
| 		if stackSize := runtime.Stack(stackInfo, false); stackSize > 0 { |  | ||||||
| 			traceLines := reTrace.Split(string(stackInfo[:stackSize]), -1) |  | ||||||
| 			if len(traceLines) != 0 { |  | ||||||
| 				attrs = append(attrs, slog.String("stacktrace", traceLines[len(traceLines)-1])) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs...) |  | ||||||
| 	r.Attrs(func(a slog.Attr) bool { |  | ||||||
| 		if a.Key == s.opts.ErrorKey { |  | ||||||
| 			if span, ok := tracer.SpanFromContext(ctx); ok { |  | ||||||
| 				span.SetStatus(tracer.SpanStatusError, a.Value.String()) |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	}) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Fatal(ctx context.Context, attrs ...interface{}) { |  | ||||||
| 	s.Log(ctx, logger.FatalLevel, attrs...) |  | ||||||
| 	os.Exit(1) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Fatalf DEPRECATED |  | ||||||
| func (s *slogLogger) Fatalf(ctx context.Context, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.FatalLevel.String()).Inc() |  | ||||||
| 	if !s.V(logger.FatalLevel) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelError+1, msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs...) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| 	os.Exit(1) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Warn(ctx context.Context, attrs ...interface{}) { |  | ||||||
| 	s.Log(ctx, logger.WarnLevel, attrs...) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Warnf DEPRECATED |  | ||||||
| func (s *slogLogger) Warnf(ctx context.Context, msg string, attrs ...interface{}) { |  | ||||||
| 	s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.WarnLevel.String()).Inc() |  | ||||||
| 	if !s.V(logger.WarnLevel) || len(attrs) == 0 { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	var pcs [1]uintptr |  | ||||||
| 	runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof] |  | ||||||
| 	r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelWarn, msg, pcs[0]) |  | ||||||
| 	for _, fn := range s.opts.ContextAttrFuncs { |  | ||||||
| 		attrs = append(attrs, fn(ctx)...) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for idx, attr := range attrs { |  | ||||||
| 		if ve, ok := attr.(error); ok && ve != nil { |  | ||||||
| 			attrs[idx] = slog.String(s.opts.ErrorKey, ve.Error()) |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	r.Add(attrs[1:]...) |  | ||||||
| 	_ = s.handler.Handle(ctx, r) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) Name() string { |  | ||||||
| 	return s.opts.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *slogLogger) String() string { |  | ||||||
| 	return "slog" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewLogger(opts ...logger.Option) logger.Logger { | func NewLogger(opts ...logger.Option) logger.Logger { | ||||||
| 	s := &slogLogger{ | 	s := &slogLogger{ | ||||||
| 		opts: logger.NewOptions(opts...), | 		opts: logger.NewOptions(opts...), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user