Fix handling of printing caller with Write, Print, and Printf. (#315)

* Add event.CallerSkipFrame(skip int)

This indicates that, for this event, we should skip an additional
specified number of frames.

This is cumulative, calling it twice for the same event will add both
numbers together, and this is in addition to any skip frame settings set
through the context, or globally.

The indended purpose is for wrappers to Msg or Msgf, so that the actual
caller is always printed correctly.

* Use CallerSkipFrame for Print, Printf, and Write.

This allows us to use the correct caller when using these 3 functions.

Co-authored-by: Zephaniah E. Loss-Cutler-Hull <warp@aehallh.com>
This commit is contained in:
Zephaniah Loss-Cutler-Hull 2021-05-13 08:22:27 -07:00 committed by GitHub
parent f09463fbe1
commit 4de2fcc128
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 12 deletions

View File

@ -26,6 +26,7 @@ type Event struct {
done func(msg string) done func(msg string)
stack bool // enable error stack trace stack bool // enable error stack trace
ch []Hook // hooks from context ch []Hook // hooks from context
skipFrame int // The number of additional frames to skip when printing the caller.
} }
func putEvent(e *Event) { func putEvent(e *Event) {
@ -62,6 +63,7 @@ func newEvent(w LevelWriter, level Level) *Event {
e.w = w e.w = w
e.level = level e.level = level
e.stack = false e.stack = false
e.skipFrame = 0
return e return e
} }
@ -685,6 +687,13 @@ func (e *Event) Interface(key string, i interface{}) *Event {
return e return e
} }
// CallerSkipFrame instructs any future Caller calls to skip the specified number of frames.
// This includes those added via hooks from the context.
func (e *Event) CallerSkipFrame(skip int) *Event {
e.skipFrame += skip
return e
}
// Caller adds the file:line of the caller with the zerolog.CallerFieldName key. // Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
// The argument skip is the number of stack frames to ascend // The argument skip is the number of stack frames to ascend
// Skip If not passed, use the global variable CallerSkipFrameCount // Skip If not passed, use the global variable CallerSkipFrameCount
@ -700,7 +709,7 @@ func (e *Event) caller(skip int) *Event {
if e == nil { if e == nil {
return e return e
} }
_, file, line, ok := runtime.Caller(skip) _, file, line, ok := runtime.Caller(skip + e.skipFrame)
if !ok { if !ok {
return e return e
} }

6
log.go
View File

@ -392,7 +392,7 @@ func (l *Logger) Log() *Event {
// Arguments are handled in the manner of fmt.Print. // Arguments are handled in the manner of fmt.Print.
func (l *Logger) Print(v ...interface{}) { func (l *Logger) Print(v ...interface{}) {
if e := l.Debug(); e.Enabled() { if e := l.Debug(); e.Enabled() {
e.Msg(fmt.Sprint(v...)) e.CallerSkipFrame(1).Msg(fmt.Sprint(v...))
} }
} }
@ -400,7 +400,7 @@ func (l *Logger) Print(v ...interface{}) {
// Arguments are handled in the manner of fmt.Printf. // Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Printf(format string, v ...interface{}) { func (l *Logger) Printf(format string, v ...interface{}) {
if e := l.Debug(); e.Enabled() { if e := l.Debug(); e.Enabled() {
e.Msg(fmt.Sprintf(format, v...)) e.CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...))
} }
} }
@ -412,7 +412,7 @@ func (l Logger) Write(p []byte) (n int, err error) {
// Trim CR added by stdlog. // Trim CR added by stdlog.
p = p[0 : n-1] p = p[0 : n-1]
} }
l.Log().Msg(string(p)) l.Log().CallerSkipFrame(1).Msg(string(p))
return return
} }

View File

@ -3,6 +3,7 @@ package log
import ( import (
"context" "context"
"fmt"
"io" "io"
"os" "os"
@ -114,13 +115,13 @@ func Log() *zerolog.Event {
// Print sends a log event using debug level and no extra field. // Print sends a log event using debug level and no extra field.
// Arguments are handled in the manner of fmt.Print. // Arguments are handled in the manner of fmt.Print.
func Print(v ...interface{}) { func Print(v ...interface{}) {
Logger.Print(v...) Logger.Debug().CallerSkipFrame(1).Msg(fmt.Sprint(v...))
} }
// Printf sends a log event using debug level and no extra field. // Printf sends a log event using debug level and no extra field.
// Arguments are handled in the manner of fmt.Printf. // Arguments are handled in the manner of fmt.Printf.
func Printf(format string, v ...interface{}) { func Printf(format string, v ...interface{}) {
Logger.Printf(format, v...) Logger.Debug().CallerSkipFrame(1).Msgf(format, v...)
} }
// Ctx returns the Logger associated with the ctx. If no logger // Ctx returns the Logger associated with the ctx. If no logger