diff --git a/zapcore/console_encoder.go b/zapcore/console_encoder.go index b7875966f..e8745743c 100644 --- a/zapcore/console_encoder.go +++ b/zapcore/console_encoder.go @@ -128,7 +128,7 @@ func (c consoleEncoder) writeContext(line *buffer.Buffer, extra []Field) { context := c.jsonEncoder.Clone().(*jsonEncoder) defer context.buf.Free() - addFields(context, extra) + context.AddFields(extra) context.closeOpenNamespaces() if context.buf.Len() == 0 { return diff --git a/zapcore/core.go b/zapcore/core.go index a1ef8b034..0bcff50de 100644 --- a/zapcore/core.go +++ b/zapcore/core.go @@ -71,7 +71,7 @@ type ioCore struct { func (c *ioCore) With(fields []Field) Core { clone := c.clone() - addFields(clone.enc, fields) + clone.enc.AddFields(fields) return clone } diff --git a/zapcore/encoder.go b/zapcore/encoder.go index f0509522b..f15e76e93 100644 --- a/zapcore/encoder.go +++ b/zapcore/encoder.go @@ -279,6 +279,8 @@ type ObjectEncoder interface { // be added. Applications can use namespaces to prevent key collisions when // injecting loggers into sub-components or third-party libraries. OpenNamespace(key string) + // AddFields adds more than multiple fields in once. + AddFields(fields []Field) } // ArrayEncoder is a strongly-typed, encoding-agnostic interface for adding diff --git a/zapcore/field.go b/zapcore/field.go index 6a5e33e2f..0b77c762d 100644 --- a/zapcore/field.go +++ b/zapcore/field.go @@ -193,9 +193,3 @@ func (f Field) Equals(other Field) bool { return f == other } } - -func addFields(enc ObjectEncoder, fields []Field) { - for i := range fields { - fields[i].AddTo(enc) - } -} diff --git a/zapcore/json_encoder.go b/zapcore/json_encoder.go index 2dc67d81e..b0d5e7c74 100644 --- a/zapcore/json_encoder.go +++ b/zapcore/json_encoder.go @@ -160,6 +160,12 @@ func (enc *jsonEncoder) OpenNamespace(key string) { enc.openNamespaces++ } +func (enc *jsonEncoder) AddFields(fields []Field) { + for _, field := range fields { + field.AddTo(enc) + } +} + func (enc *jsonEncoder) AddString(key, val string) { enc.addKey(key) enc.AppendString(val) @@ -358,7 +364,7 @@ func (enc *jsonEncoder) EncodeEntry(ent Entry, fields []Field) (*buffer.Buffer, final.addElementSeparator() final.buf.Write(enc.buf.Bytes()) } - addFields(final, fields) + final.AddFields(fields) final.closeOpenNamespaces() if ent.Stack != "" && final.StacktraceKey != "" { final.AddString(final.StacktraceKey, ent.Stack) diff --git a/zapcore/memory_encoder.go b/zapcore/memory_encoder.go index 6ef85b09c..520180398 100644 --- a/zapcore/memory_encoder.go +++ b/zapcore/memory_encoder.go @@ -132,6 +132,13 @@ func (m *MapObjectEncoder) OpenNamespace(k string) { m.cur = ns } +// AddFields implements ObjectEncoder. +func (m *MapObjectEncoder) AddFields(fields []Field) { + for _, field := range fields { + field.AddTo(m) + } +} + // sliceArrayEncoder is an ArrayEncoder backed by a simple []interface{}. Like // the MapObjectEncoder, it's not designed for production use. type sliceArrayEncoder struct { diff --git a/zapcore/memory_encoder_test.go b/zapcore/memory_encoder_test.go index 5ca9577ae..9bb182947 100644 --- a/zapcore/memory_encoder_test.go +++ b/zapcore/memory_encoder_test.go @@ -290,3 +290,12 @@ func TestMapObjectEncoderReflectionFailures(t *testing.T) { "Expected encoder to use empty values on errors.", ) } + +func TestMapObjectEncoderAddaFields(t *testing.T) { + enc := NewMapObjectEncoder() + enc.AddFields([]Field{ + {Key: "AddStr", Type: StringType, String: "StrVal"}, + {Key: "AddInt", Type: Int64Type, Integer: int64(1)}, + }) + assert.Equal(t, 2, len(enc.Fields)) +}