Add the ability to skip a specified number of stack frames on a per context basis. Before this toe CallerSkipFrameCount could only be set globally.
This commit is contained in:
parent
8e5449ab35
commit
651d361cfe
38
context.go
38
context.go
|
@ -2,6 +2,7 @@ package zerolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -347,14 +348,31 @@ func (c Context) Interface(key string, i interface{}) Context {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
type callerHook struct{}
|
type callerHook struct {
|
||||||
|
callerSkipFrameCount int
|
||||||
func (ch callerHook) Run(e *Event, level Level, msg string) {
|
|
||||||
// Extra frames to skip (added by hook infra).
|
|
||||||
e.caller(CallerSkipFrameCount + contextCallerSkipFrameCount)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ch = callerHook{}
|
func newCallerHook(skipFrameCount int) callerHook {
|
||||||
|
return callerHook{callerSkipFrameCount: skipFrameCount}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ch callerHook) Run(e *Event, level Level, msg string) {
|
||||||
|
switch ch.callerSkipFrameCount {
|
||||||
|
case useGlobalSkipFrameCount:
|
||||||
|
// Extra frames to skip (added by hook infra).
|
||||||
|
e.caller(CallerSkipFrameCount + contextCallerSkipFrameCount)
|
||||||
|
default:
|
||||||
|
// Extra frames to skip (added by hook infra).
|
||||||
|
e.caller(ch.callerSkipFrameCount + contextCallerSkipFrameCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// useGlobalSkipFrameCount acts as a flag to informat callerHook.Run
|
||||||
|
// to use the global CallerSkipFrameCount.
|
||||||
|
const useGlobalSkipFrameCount = math.MinInt32
|
||||||
|
|
||||||
|
// ch is the default caller hook using the global CallerSkipFrameCount.
|
||||||
|
var ch = newCallerHook(useGlobalSkipFrameCount)
|
||||||
|
|
||||||
// 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.
|
||||||
func (c Context) Caller() Context {
|
func (c Context) Caller() Context {
|
||||||
|
@ -362,6 +380,14 @@ func (c Context) Caller() Context {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CallerWithSkipFrameCount adds the file:line of the caller with the zerolog.CallerFieldName key.
|
||||||
|
// The specified skipFrameCount int will override the global CallerSkipFrameCount for this context's respective logger.
|
||||||
|
// If set to -1 the global CallerSkipFrameCount will be used.
|
||||||
|
func (c Context) CallerWithSkipFrameCount(skipFrameCount int) Context {
|
||||||
|
c.l = c.l.Hook(newCallerHook(skipFrameCount))
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
type stackTraceHook struct{}
|
type stackTraceHook struct{}
|
||||||
|
|
||||||
func (sh stackTraceHook) Run(e *Event, level Level, msg string) {
|
func (sh stackTraceHook) Run(e *Event, level Level, msg string) {
|
||||||
|
|
14
log_test.go
14
log_test.go
|
@ -107,6 +107,20 @@ func TestWith(t *testing.T) {
|
||||||
if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11.101,"float64":12.30303,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
|
if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11.101,"float64":12.30303,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
|
||||||
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate CallerWithSkipFrameCount.
|
||||||
|
out.Reset()
|
||||||
|
_, file, line, _ = runtime.Caller(0)
|
||||||
|
caller = fmt.Sprintf("%s:%d", file, line+5)
|
||||||
|
log = ctx.CallerWithSkipFrameCount(3).Logger()
|
||||||
|
func() {
|
||||||
|
log.Log().Msg("")
|
||||||
|
}()
|
||||||
|
// The above line is a little contrived, but the line above should be the line due
|
||||||
|
// to the extra frame skip.
|
||||||
|
if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11.101,"float64":12.30303,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
|
||||||
|
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFieldsMap(t *testing.T) {
|
func TestFieldsMap(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue