|
|
|
@ -15,6 +15,9 @@ import (
|
|
|
|
|
"go.unistack.org/micro/v3/tracer"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const badKey = "!BADKEY"
|
|
|
|
|
const emptyMSg = "!EMPTYMSG"
|
|
|
|
|
|
|
|
|
|
var reTrace = regexp.MustCompile(`.*/slog/logger\.go.*\n`)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
@ -152,22 +155,39 @@ func (s *slogLogger) Init(opts ...logger.Option) error {
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc()
|
|
|
|
|
if !s.V(lvl) {
|
|
|
|
|
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), fmt.Sprintf("%s", attrs[0]), pcs[0])
|
|
|
|
|
for _, fn := range s.opts.ContextAttrFuncs {
|
|
|
|
|
attrs = append(attrs, fn(ctx)...)
|
|
|
|
|
|
|
|
|
|
msg := attrs[0]
|
|
|
|
|
attrs = prepareAttributes(attrs[1:])
|
|
|
|
|
|
|
|
|
|
ve, hasErr := msg.(error)
|
|
|
|
|
if hasErr && ve != nil {
|
|
|
|
|
attrs = append(attrs, slog.String(s.opts.ErrorKey, ve.Error()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, fn := range s.opts.ContextAttrFuncs {
|
|
|
|
|
a := prepareAttributes(fn(ctx))
|
|
|
|
|
attrs = append(attrs, a...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !hasErr {
|
|
|
|
|
for idx, attr := range attrs {
|
|
|
|
|
if ve, ok := attr.(error); ok && ve != nil {
|
|
|
|
|
if ve, hasErr = attr.(error); hasErr && ve != nil {
|
|
|
|
|
if idx%2 == 1 {
|
|
|
|
|
attrs = append(attrs, slog.String(s.opts.ErrorKey, ve.Error()))
|
|
|
|
|
} else {
|
|
|
|
|
attrs[idx] = 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 {
|
|
|
|
@ -177,22 +197,18 @@ func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interfa
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), loggerToSlogLevel(lvl), fmt.Sprintf("%s", msg), pcs[0])
|
|
|
|
|
r.Add(attrs...)
|
|
|
|
|
_ = 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) {
|
|
|
|
|
if !s.V(lvl) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -231,30 +247,13 @@ func (s *slogLogger) Logf(ctx context.Context, lvl logger.Level, msg string, att
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Info(ctx context.Context, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.InfoLevel.String()).Inc()
|
|
|
|
|
if !s.V(logger.InfoLevel) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelInfo, fmt.Sprintf("%s", attrs[0]), 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)
|
|
|
|
|
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) {
|
|
|
|
|
if !s.V(logger.InfoLevel) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -275,30 +274,13 @@ func (s *slogLogger) Infof(ctx context.Context, msg string, attrs ...interface{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Debug(ctx context.Context, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.DebugLevel.String()).Inc()
|
|
|
|
|
if !s.V(logger.DebugLevel) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelDebug, fmt.Sprintf("%s", attrs[0]), 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)
|
|
|
|
|
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) {
|
|
|
|
|
if !s.V(logger.DebugLevel) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -319,30 +301,13 @@ func (s *slogLogger) Debugf(ctx context.Context, msg string, attrs ...interface{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Trace(ctx context.Context, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.TraceLevel.String()).Inc()
|
|
|
|
|
if !s.V(logger.TraceLevel) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelDebug-1, fmt.Sprintf("%s", attrs[0]), 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)
|
|
|
|
|
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) {
|
|
|
|
|
if !s.V(logger.TraceLevel) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -363,48 +328,13 @@ func (s *slogLogger) Tracef(ctx context.Context, msg string, attrs ...interface{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Error(ctx context.Context, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.ErrorLevel.String()).Inc()
|
|
|
|
|
if !s.V(logger.ErrorLevel) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelError, fmt.Sprintf("%s", attrs[0]), 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[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)
|
|
|
|
|
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) {
|
|
|
|
|
if !s.V(logger.ErrorLevel) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -443,31 +373,14 @@ func (s *slogLogger) Errorf(ctx context.Context, msg string, attrs ...interface{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Fatal(ctx context.Context, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.FatalLevel.String()).Inc()
|
|
|
|
|
if !s.V(logger.FatalLevel) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelError+1, fmt.Sprintf("%s", attrs[0]), 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)
|
|
|
|
|
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) {
|
|
|
|
|
if !s.V(logger.FatalLevel) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -489,30 +402,13 @@ func (s *slogLogger) Fatalf(ctx context.Context, msg string, attrs ...interface{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *slogLogger) Warn(ctx context.Context, attrs ...interface{}) {
|
|
|
|
|
s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.WarnLevel.String()).Inc()
|
|
|
|
|
if !s.V(logger.WarnLevel) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
|
runtime.Callers(s.opts.CallerSkipCount, pcs[:]) // skip [Callers, Infof]
|
|
|
|
|
r := slog.NewRecord(s.opts.TimeFunc(), slog.LevelWarn, fmt.Sprintf("%s", attrs[0]), 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)
|
|
|
|
|
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) {
|
|
|
|
|
if !s.V(logger.WarnLevel) || len(attrs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
var pcs [1]uintptr
|
|
|
|
@ -581,3 +477,13 @@ func slogToLoggerLevel(level slog.Level) logger.Level {
|
|
|
|
|
return logger.InfoLevel
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func prepareAttributes(attrs []interface{}) []interface{} {
|
|
|
|
|
|
|
|
|
|
if len(attrs)%2 == 1 {
|
|
|
|
|
attrs = append(attrs, badKey)
|
|
|
|
|
attrs[len(attrs)-1], attrs[len(attrs)-2] = attrs[len(attrs)-2], attrs[len(attrs)-1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return attrs
|
|
|
|
|
}
|
|
|
|
|