diff options
Diffstat (limited to 'modules/log/logger_impl.go')
-rw-r--r-- | modules/log/logger_impl.go | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/modules/log/logger_impl.go b/modules/log/logger_impl.go index 76dd5f43fb..551c1454aa 100644 --- a/modules/log/logger_impl.go +++ b/modules/log/logger_impl.go @@ -5,6 +5,7 @@ package log import ( "context" + "reflect" "runtime" "strings" "sync" @@ -175,29 +176,42 @@ func (l *LoggerImpl) IsEnabled() bool { return l.level.Load() < int32(FATAL) && len(l.eventWriters) > 0 } +func asLogStringer(v any) LogStringer { + if s, ok := v.(LogStringer); ok { + return s + } else if a := reflect.ValueOf(v); a.Kind() == reflect.Struct { + // in case the receiver is a pointer, but the value is a struct + vp := reflect.New(a.Type()) + vp.Elem().Set(a) + if s, ok := vp.Interface().(LogStringer); ok { + return s + } + } + return nil +} + // Log prepares the log event, if the level matches, the event will be sent to the writers -func (l *LoggerImpl) Log(skip int, level Level, format string, logArgs ...any) { - if Level(l.level.Load()) > level { +func (l *LoggerImpl) Log(skip int, event *Event, format string, logArgs ...any) { + if Level(l.level.Load()) > event.Level { return } - event := &Event{ - Time: time.Now(), - Level: level, - Caller: "?()", + if event.Time.IsZero() { + event.Time = time.Now() } - - pc, filename, line, ok := runtime.Caller(skip + 1) - if ok { - fn := runtime.FuncForPC(pc) - if fn != nil { - event.Caller = fn.Name() + "()" + if event.Caller == "" { + pc, filename, line, ok := runtime.Caller(skip + 1) + if ok { + fn := runtime.FuncForPC(pc) + if fn != nil { + fnName := fn.Name() + event.Caller = strings.ReplaceAll(fnName, "[...]", "") + "()" // generic function names are "foo[...]" + } + } + event.Filename, event.Line = strings.TrimPrefix(filename, projectPackagePrefix), line + if l.stacktraceLevel.Load() <= int32(event.Level) { + event.Stacktrace = Stack(skip + 1) } - } - event.Filename, event.Line = strings.TrimPrefix(filename, projectPackagePrefix), line - - if l.stacktraceLevel.Load() <= int32(level) { - event.Stacktrace = Stack(skip + 1) } // get a simple text message without color @@ -207,11 +221,11 @@ func (l *LoggerImpl) Log(skip int, level Level, format string, logArgs ...any) { // handle LogStringer values for i, v := range msgArgs { if cv, ok := v.(*ColoredValue); ok { - if s, ok := cv.v.(LogStringer); ok { - cv.v = logStringFormatter{v: s} + if ls := asLogStringer(cv.v); ls != nil { + cv.v = logStringFormatter{v: ls} } - } else if s, ok := v.(LogStringer); ok { - msgArgs[i] = logStringFormatter{v: s} + } else if ls := asLogStringer(v); ls != nil { + msgArgs[i] = logStringFormatter{v: ls} } } |