aboutsummaryrefslogtreecommitdiffstats
path: root/modules/log/logger_impl.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/log/logger_impl.go')
-rw-r--r--modules/log/logger_impl.go56
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}
}
}