From 9a9fa7d4b5f07a9b634983678a65b5525f81e58b Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 9 Jul 2019 10:27:28 -0400 Subject: [PATCH] Make API for omitting keys more approachable. (#725) * Explicitly document key omission in encoding Currently encoders will omit fields when encoding log entries if the key configured for that field is set to the empty string. However, this behavior isn't documented or specified explicitly as being part of the interface for encoding. This adds documentation to the `Encoder` interface that explicitly outlines the behavior that should be implemented when omitting fields. * Add key for omission to package API The empty string can be used to omit a key from a log line. However, there's no explicitly exposed API for using this behavior. This cleans up the API for users by allowing them to use a constant for omitting the key instead of throwing around `""` everywhere, or making their own constant and hoping that `""` will always omit the key. --- zapcore/encoder.go | 6 +++++- zapcore/encoder_test.go | 12 ++++++------ zapcore/entry.go | 3 ++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/zapcore/encoder.go b/zapcore/encoder.go index f0509522b..9cb0f5807 100644 --- a/zapcore/encoder.go +++ b/zapcore/encoder.go @@ -31,6 +31,9 @@ import ( // behavior. const DefaultLineEnding = "\n" +// OmitKey defines the key to use when callers want to remove a key from log output. +const OmitKey = "" + // A LevelEncoder serializes a Level to a primitive type. type LevelEncoder func(Level, PrimitiveArrayEncoder) @@ -343,6 +346,7 @@ type Encoder interface { Clone() Encoder // EncodeEntry encodes an entry and fields, along with any accumulated - // context, into a byte buffer and returns it. + // context, into a byte buffer and returns it. Any fields that are empty, + // including fields on the `Entry` type, should be omitted. EncodeEntry(Entry, []Field) (*buffer.Buffer, error) } diff --git a/zapcore/encoder_test.go b/zapcore/encoder_test.go index 04641678c..b7d31a161 100644 --- a/zapcore/encoder_test.go +++ b/zapcore/encoder_test.go @@ -121,7 +121,7 @@ func TestEncoderConfiguration(t *testing.T) { { desc: "skip level if LevelKey is omitted", cfg: EncoderConfig{ - LevelKey: "", + LevelKey: OmitKey, TimeKey: "T", MessageKey: "M", NameKey: "N", @@ -140,7 +140,7 @@ func TestEncoderConfiguration(t *testing.T) { desc: "skip timestamp if TimeKey is omitted", cfg: EncoderConfig{ LevelKey: "L", - TimeKey: "", + TimeKey: OmitKey, MessageKey: "M", NameKey: "N", CallerKey: "C", @@ -159,7 +159,7 @@ func TestEncoderConfiguration(t *testing.T) { cfg: EncoderConfig{ LevelKey: "L", TimeKey: "T", - MessageKey: "", + MessageKey: OmitKey, NameKey: "N", CallerKey: "C", StacktraceKey: "S", @@ -178,7 +178,7 @@ func TestEncoderConfiguration(t *testing.T) { LevelKey: "L", TimeKey: "T", MessageKey: "M", - NameKey: "", + NameKey: OmitKey, CallerKey: "C", StacktraceKey: "S", LineEnding: base.LineEnding, @@ -197,7 +197,7 @@ func TestEncoderConfiguration(t *testing.T) { TimeKey: "T", MessageKey: "M", NameKey: "N", - CallerKey: "", + CallerKey: OmitKey, StacktraceKey: "S", LineEnding: base.LineEnding, EncodeTime: base.EncodeTime, @@ -216,7 +216,7 @@ func TestEncoderConfiguration(t *testing.T) { MessageKey: "M", NameKey: "N", CallerKey: "C", - StacktraceKey: "", + StacktraceKey: OmitKey, LineEnding: base.LineEnding, EncodeTime: base.EncodeTime, EncodeDuration: base.EncodeDuration, diff --git a/zapcore/entry.go b/zapcore/entry.go index 7d9893f33..8273abdf0 100644 --- a/zapcore/entry.go +++ b/zapcore/entry.go @@ -136,7 +136,8 @@ func (ec EntryCaller) TrimmedPath() string { // 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. +// information are available for inspection and modification. Any fields left +// empty will be omitted when encoding. // // Entries are pooled, so any functions that accept them MUST be careful not to // retain references to them.