Skip to content

Commit 87577d8

Browse files
justinhwangabhinav
andauthored
zapcore: Ignore nil Entry.Time in encoders (#1369)
Per the comment on `Encoder.EncodeEntry`, any fields that are empty including fields on the `Entry` type should be omitted. Omit the `Time` field when we have empty time. This also aligns with slog.Handler contract. Refs #1334 Discovered by #1335 --------- Co-authored-by: Abhinav Gupta <[email protected]>
1 parent 54430cb commit 87577d8

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed

zapcore/console_encoder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (c consoleEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer,
7777
// If this ever becomes a performance bottleneck, we can implement
7878
// ArrayEncoder for our plain-text format.
7979
arr := getSliceEncoder()
80-
if c.TimeKey != "" && c.EncodeTime != nil {
80+
if c.TimeKey != "" && c.EncodeTime != nil && !ent.Time.IsZero() {
8181
c.EncodeTime(ent.Time, arr)
8282
}
8383
if c.LevelKey != "" && c.EncodeLevel != nil {

zapcore/console_encoder_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package zapcore_test
2121

2222
import (
2323
"testing"
24+
"time"
2425

2526
"github.com/stretchr/testify/assert"
2627
. "go.uber.org/zap/zapcore"
@@ -35,6 +36,50 @@ var testEntry = Entry{
3536
Caller: EntryCaller{Defined: true, File: "foo.go", Line: 42, Function: "foo.Foo"},
3637
}
3738

39+
func TestConsoleEncodeEntry(t *testing.T) {
40+
tests := []struct {
41+
desc string
42+
expected string
43+
ent Entry
44+
fields []Field
45+
}{
46+
{
47+
desc: "info no fields",
48+
expected: "2018-06-19T16:33:42Z\tinfo\tbob\tlob law\n",
49+
ent: Entry{
50+
Level: InfoLevel,
51+
Time: time.Date(2018, 6, 19, 16, 33, 42, 99, time.UTC),
52+
LoggerName: "bob",
53+
Message: "lob law",
54+
},
55+
},
56+
{
57+
desc: "zero_time_omitted",
58+
expected: "info\tname\tmessage\n",
59+
ent: Entry{
60+
Level: InfoLevel,
61+
Time: time.Time{},
62+
LoggerName: "name",
63+
Message: "message",
64+
},
65+
},
66+
}
67+
68+
cfg := testEncoderConfig()
69+
cfg.EncodeTime = RFC3339TimeEncoder
70+
enc := NewConsoleEncoder(cfg)
71+
72+
for _, tt := range tests {
73+
t.Run(tt.desc, func(t *testing.T) {
74+
buf, err := enc.EncodeEntry(tt.ent, tt.fields)
75+
if assert.NoError(t, err, "Unexpected console encoding error.") {
76+
assert.Equal(t, tt.expected, buf.String(), "Incorrect encoded entry.")
77+
}
78+
buf.Free()
79+
})
80+
}
81+
}
82+
3883
func TestConsoleSeparator(t *testing.T) {
3984
tests := []struct {
4085
desc string

zapcore/json_encoder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ func (enc *jsonEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer,
372372
final.AppendString(ent.Level.String())
373373
}
374374
}
375-
if final.TimeKey != "" {
375+
if final.TimeKey != "" && !ent.Time.IsZero() {
376376
final.AddTime(final.TimeKey, ent.Time)
377377
}
378378
if ent.LoggerName != "" && final.NameKey != "" {

zapcore/json_encoder_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,20 @@ func TestJSONEncodeEntry(t *testing.T) {
109109
}),
110110
},
111111
},
112+
{
113+
desc: "zero_time_omitted",
114+
expected: `{
115+
"L": "info",
116+
"N": "name",
117+
"M": "message"
118+
}`,
119+
ent: zapcore.Entry{
120+
Level: zapcore.InfoLevel,
121+
Time: time.Time{},
122+
LoggerName: "name",
123+
Message: "message",
124+
},
125+
},
112126
}
113127

114128
enc := zapcore.NewJSONEncoder(zapcore.EncoderConfig{

0 commit comments

Comments
 (0)