Add support for customizing caller field format (#133) (#134)

This commit is contained in:
mikeyrcamp 2019-02-20 14:39:29 -05:00 committed by Olivier Poitrey
parent 4daee2b758
commit 299ff038c1
3 changed files with 45 additions and 3 deletions

View File

@ -5,7 +5,6 @@ import (
"net" "net"
"os" "os"
"runtime" "runtime"
"strconv"
"sync" "sync"
"time" "time"
) )
@ -673,7 +672,7 @@ func (e *Event) caller(skip int) *Event {
if !ok { if !ok {
return e return e
} }
e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), file+":"+strconv.Itoa(line)) e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(file, line))
return e return e
} }

View File

@ -1,6 +1,9 @@
package zerolog package zerolog
import "time" import (
"strconv"
"time"
)
import "sync/atomic" import "sync/atomic"
var ( var (
@ -22,6 +25,11 @@ var (
// CallerSkipFrameCount is the number of stack frames to skip to find the caller. // CallerSkipFrameCount is the number of stack frames to skip to find the caller.
CallerSkipFrameCount = 2 CallerSkipFrameCount = 2
// CallerMarshalFunc allows customization of global caller marshaling
CallerMarshalFunc = func(file string, line int) string {
return file+":"+strconv.Itoa(line)
}
// ErrorStackFieldName is the field name used for error stacks. // ErrorStackFieldName is the field name used for error stacks.
ErrorStackFieldName = "stack" ErrorStackFieldName = "stack"

View File

@ -7,6 +7,8 @@ import (
"net" "net"
"reflect" "reflect"
"runtime" "runtime"
"strconv"
"strings"
"testing" "testing"
"time" "time"
) )
@ -641,6 +643,39 @@ func TestErrorMarshalFunc(t *testing.T) {
} }
} }
func TestCallerMarshalFunc(t *testing.T) {
out := &bytes.Buffer{}
log := New(out)
// test default behaviour this is really brittle due to the line numbers
// actually mattering for validation
_, file, line, _ := runtime.Caller(0)
caller := fmt.Sprintf("%s:%d", file, line + 2)
log.Log().Caller().Msg("msg")
if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"` + caller + `","message":"msg"}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
}
out.Reset()
// test custom behavior. In this case we'll take just the last directory
origCallerMarshalFunc := CallerMarshalFunc
defer func() { CallerMarshalFunc = origCallerMarshalFunc }()
CallerMarshalFunc = func(file string, line int) string {
parts := strings.Split(file, "/")
if len(parts) > 1 {
return strings.Join(parts[len(parts)-2:], "/")+":"+strconv.Itoa(line)
} else {
return file+":"+strconv.Itoa(line)
}
}
_, file, line, _ = runtime.Caller(0)
caller = CallerMarshalFunc(file, line+2)
log.Log().Caller().Msg("msg")
if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"` + caller + `","message":"msg"}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
}
}
type errWriter struct { type errWriter struct {
error error
} }