Skip to content

Commit

Permalink
Add a shorter EncodeCaller variant
Browse files Browse the repository at this point in the history
  • Loading branch information
Akshay Shah committed Mar 14, 2017
1 parent 77a9fcc commit f785f2a
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 23 deletions.
3 changes: 1 addition & 2 deletions benchmarks/zap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ var _jane = user{

func newZapLogger(lvl zapcore.Level) *zap.Logger {
// use the canned production encoder configuration
cfg := zap.NewProductionConfig()
enc := zapcore.NewJSONEncoder(cfg.EncoderConfig)
enc := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
return zap.New(zapcore.NewCore(
enc,
&zaptest.Discarder{},
Expand Down
4 changes: 2 additions & 2 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func NewProductionEncoderConfig() zapcore.EncoderConfig {
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.EpochTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.FullPathCallerEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
}

Expand Down Expand Up @@ -127,7 +127,7 @@ func NewDevelopmentEncoderConfig() zapcore.EncoderConfig {
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.FullPathCallerEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
}

Expand Down
20 changes: 15 additions & 5 deletions zapcore/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,18 +165,28 @@ func (e *DurationEncoder) UnmarshalText(text []byte) error {
// A CallerEncoder serializes an EntryCaller to a primitive type.
type CallerEncoder func(EntryCaller, PrimitiveArrayEncoder)

// FullPathCallerEncoder serializes a caller in /full/path/file:line format.
func FullPathCallerEncoder(caller EntryCaller, enc PrimitiveArrayEncoder) {
// FullCallerEncoder serializes a caller in /full/path/to/package/file:line
// format.
func FullCallerEncoder(caller EntryCaller, enc PrimitiveArrayEncoder) {
// TODO: consider using a byte-oriented API to save an allocation.
enc.AppendString(caller.String())
}

// UnmarshalText unmarshals text to a CallerEncoder.
// FIXME: Support more options.
// ShortCallerEncoder serializes a caller in package/file:line format, trimming
// all but the final directory from the full path.
func ShortCallerEncoder(caller EntryCaller, enc PrimitiveArrayEncoder) {
// TODO: consider using a byte-oriented API to save an allocation.
enc.AppendString(caller.TrimmedPath())
}

// UnmarshalText unmarshals text to a CallerEncoder. "full" is unmarshaled to
// FullCallerEncoder and anything else is unmarshaled to ShortCallerEncoder.
func (e *CallerEncoder) UnmarshalText(text []byte) error {
switch string(text) {
case "full":
*e = FullCallerEncoder
default:
*e = FullPathCallerEncoder
*e = ShortCallerEncoder
}
return nil
}
Expand Down
8 changes: 5 additions & 3 deletions zapcore/encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func testEncoderConfig() EncoderConfig {
EncodeTime: EpochTimeEncoder,
EncodeLevel: LowercaseLevelEncoder,
EncodeDuration: SecondsDurationEncoder,
EncodeCaller: FullPathCallerEncoder,
EncodeCaller: ShortCallerEncoder,
}
}

Expand Down Expand Up @@ -490,8 +490,10 @@ func TestCallerEncoders(t *testing.T) {
name string
expected interface{} // output of serializing caller
}{
{"", "/home/jack/src/github.com/foo/foo.go:42"},
{"something-random", "/home/jack/src/github.com/foo/foo.go:42"},
{"", "foo/foo.go:42"},
{"something-random", "foo/foo.go:42"},
{"short", "foo/foo.go:42"},
{"full", "/home/jack/src/github.com/foo/foo.go:42"},
}

for _, tt := range tests {
Expand Down
39 changes: 36 additions & 3 deletions zapcore/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ package zapcore

import (
"fmt"
"os"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -74,11 +76,16 @@ type EntryCaller struct {
Line int
}

// String returns a "file:line" string if the EntryCaller is Defined, and the
// empty string otherwise.
// String returns the full path and line number of the caller.
func (ec EntryCaller) String() string {
return ec.FullPath()
}

// FullPath returns a /full/path/to/package/file:line description of the
// caller.
func (ec EntryCaller) FullPath() string {
if !ec.Defined {
return ""
return "undefined"
}
buf := bufferpool.Get()
buf.AppendString(ec.File)
Expand All @@ -89,6 +96,32 @@ func (ec EntryCaller) String() string {
return caller
}

// TrimmedPath returns a package/file:line description of the caller,
// preserving only the leaf directory name and file name.
func (ec EntryCaller) TrimmedPath() string {
if !ec.Defined {
return "undefined"
}
// Find the last separator.
idx := strings.LastIndexByte(ec.File, os.PathSeparator)
if idx == -1 {
return ec.FullPath()
}
// Find the penultimate separator.
idx = strings.LastIndexByte(ec.File[:idx], os.PathSeparator)
if idx == -1 {
return ec.FullPath()
}
buf := bufferpool.Get()
// Keep everything after the penultimate separator.
buf.AppendString(ec.File[idx+1:])
buf.AppendByte(':')
buf.AppendInt(int64(ec.Line))
caller := buf.String()
bufferpool.Put(buf)
return caller
}

// An Entry represents a complete log message. The entry's structured context
// is already serialized, but the log level, time, message, and call site
// information are available for inspection and modification.
Expand Down
29 changes: 21 additions & 8 deletions zapcore/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,31 @@ func TestPutNilEntry(t *testing.T) {

func TestEntryCaller(t *testing.T) {
tests := []struct {
ok bool
want EntryCaller
str string
caller EntryCaller
full string
short string
}{
{true, EntryCaller{PC: 100, Defined: true, File: "foo.go", Line: 42}, "foo.go:42"},
{false, EntryCaller{}, ""},
{
caller: NewEntryCaller(100, "/path/to/foo.go", 42, false),
full: "undefined",
short: "undefined",
},
{
caller: NewEntryCaller(100, "/path/to/foo.go", 42, true),
full: "/path/to/foo.go:42",
short: "to/foo.go:42",
},
{
caller: NewEntryCaller(100, "to/foo.go", 42, true),
full: "to/foo.go:42",
short: "to/foo.go:42",
},
}

for _, tt := range tests {
caller := NewEntryCaller(100, "foo.go", 42, tt.ok)
assert.Equal(t, tt.want, caller, "Unexpected output from NewEntryCaller.")
assert.Equal(t, tt.str, caller.String(), "Unexpected string output from EntryCaller")
assert.Equal(t, tt.full, tt.caller.String(), "Unexpected string from EntryCaller.")
assert.Equal(t, tt.full, tt.caller.FullPath(), "Unexpected FullPath from EntryCaller.")
assert.Equal(t, tt.short, tt.caller.TrimmedPath(), "Unexpected TrimmedPath from EntryCaller.")
}
}

Expand Down

0 comments on commit f785f2a

Please sign in to comment.