From d58d6f95fc280b9fb85dcfb061f0cd5b1763ed64 Mon Sep 17 00:00:00 2001 From: Akshay Shah Date: Fri, 13 Apr 2018 12:56:13 -0700 Subject: [PATCH 1/4] Test on Go 1.10 and 1.9 Update our Travis configuration to test on Go 1.9 and 1.10, dropping 1.8. --- .travis.yml | 4 ++-- Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9dd566c2e..da1100b7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: go sudo: false go: - - 1.8 - - 1.9 + - "1.9" + - "1.10" go_import_path: go.uber.org/zap env: global: diff --git a/Makefile b/Makefile index 026eb2a2e..ef7893b3b 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ PKG_FILES ?= *.go zapcore benchmarks buffer zapgrpc zaptest zaptest/observer int # stable release. GO_VERSION := $(shell go version | cut -d " " -f 3) GO_MINOR_VERSION := $(word 2,$(subst ., ,$(GO_VERSION))) -LINTABLE_MINOR_VERSIONS := 9 +LINTABLE_MINOR_VERSIONS := 10 ifneq ($(filter $(LINTABLE_MINOR_VERSIONS),$(GO_MINOR_VERSION)),) SHOULD_LINT := true endif From ab08e4155c73b12f8dc5821c32fd80285d7cd156 Mon Sep 17 00:00:00 2001 From: Akshay Shah Date: Fri, 13 Apr 2018 12:59:53 -0700 Subject: [PATCH 2/4] Drop support for Go 1.8 Drop support for Go 1.8. Since all supported versions of Go now have type aliases, we can drop some duplicated code. --- zaptest/writer.go | 88 ++++++++--------------------------------- zaptest/writer_go_19.go | 47 ---------------------- zaptest/writer_test.go | 40 ------------------- 3 files changed, 17 insertions(+), 158 deletions(-) delete mode 100644 zaptest/writer_go_19.go diff --git a/zaptest/writer.go b/zaptest/writer.go index 64ed126cb..0701630e1 100644 --- a/zaptest/writer.go +++ b/zaptest/writer.go @@ -18,81 +18,27 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -// +build !go1.9 - package zaptest -import ( - "bytes" - "errors" - "io/ioutil" - "strings" -) - -// A Syncer is a spy for the Sync portion of zapcore.WriteSyncer. -type Syncer struct { - err error - called bool -} - -// SetError sets the error that the Sync method will return. -func (s *Syncer) SetError(err error) { - s.err = err -} - -// Sync records that it was called, then returns the user-supplied error (if -// any). -func (s *Syncer) Sync() error { - s.called = true - return s.err -} - -// Called reports whether the Sync method was called. -func (s *Syncer) Called() bool { - return s.called -} +import "go.uber.org/zap/internal/ztest" -// A Discarder sends all writes to ioutil.Discard. -type Discarder struct{ Syncer } +type ( + // A Syncer is a spy for the Sync portion of zapcore.WriteSyncer. + Syncer = ztest.Syncer -// Write implements io.Writer. -func (d *Discarder) Write(b []byte) (int, error) { - return ioutil.Discard.Write(b) -} + // A Discarder sends all writes to ioutil.Discard. + Discarder = ztest.Discarder -// FailWriter is a WriteSyncer that always returns an error on writes. -type FailWriter struct{ Syncer } + // FailWriter is a WriteSyncer that always returns an error on writes. + FailWriter = ztest.FailWriter -// Write implements io.Writer. -func (w FailWriter) Write(b []byte) (int, error) { - return len(b), errors.New("failed") -} + // ShortWriter is a WriteSyncer whose write method never returns an error, + // but always reports that it wrote one byte less than the input slice's + // length (thus, a "short write"). + ShortWriter = ztest.ShortWriter -// ShortWriter is a WriteSyncer whose write method never fails, but -// nevertheless fails to the last byte of the input. -type ShortWriter struct{ Syncer } - -// Write implements io.Writer. -func (w ShortWriter) Write(b []byte) (int, error) { - return len(b) - 1, nil -} - -// Buffer is an implementation of zapcore.WriteSyncer that sends all writes to -// a bytes.Buffer. It has convenience methods to split the accumulated buffer -// on newlines. -type Buffer struct { - bytes.Buffer - Syncer -} - -// Lines returns the current buffer contents, split on newlines. -func (b *Buffer) Lines() []string { - output := strings.Split(b.String(), "\n") - return output[:len(output)-1] -} - -// Stripped returns the current buffer contents with the last trailing newline -// stripped. -func (b *Buffer) Stripped() string { - return strings.TrimRight(b.String(), "\n") -} + // Buffer is an implementation of zapcore.WriteSyncer that sends all writes to + // a bytes.Buffer. It has convenience methods to split the accumulated buffer + // on newlines. + Buffer = ztest.Buffer +) diff --git a/zaptest/writer_go_19.go b/zaptest/writer_go_19.go deleted file mode 100644 index c9cc763de..000000000 --- a/zaptest/writer_go_19.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2016 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// Type aliases are available only in Go 1.9 and later. -// +build go1.9 - -package zaptest - -import "go.uber.org/zap/internal/ztest" - -type ( - // A Syncer is a spy for the Sync portion of zapcore.WriteSyncer. - Syncer = ztest.Syncer - - // A Discarder sends all writes to ioutil.Discard. - Discarder = ztest.Discarder - - // FailWriter is a WriteSyncer that always returns an error on writes. - FailWriter = ztest.FailWriter - - // ShortWriter is a WriteSyncer whose write method never returns an error, - // but always reports that it wrote one byte less than the input slice's - // length (thus, a "short write"). - ShortWriter = ztest.ShortWriter - - // Buffer is an implementation of zapcore.WriteSyncer that sends all writes to - // a bytes.Buffer. It has convenience methods to split the accumulated buffer - // on newlines. - Buffer = ztest.Buffer -) diff --git a/zaptest/writer_test.go b/zaptest/writer_test.go index 07b8ef398..c18f18a35 100644 --- a/zaptest/writer_test.go +++ b/zaptest/writer_test.go @@ -21,52 +21,12 @@ package zaptest import ( - "bufio" "errors" - "os" - "strings" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) -func readCode(t testing.TB, fname string) []string { - f, err := os.Open(fname) - require.NoError(t, err, "Failed to read %s.", fname) - defer func() { - require.NoError(t, f.Close(), "Error closing file %s.", fname) - }() - - var lines []string - s := bufio.NewScanner(f) - for s.Scan() { - l := s.Text() - if len(l) == 0 { - continue - } - if strings.HasPrefix(l, "//") { - continue - } - if strings.HasPrefix(l, "package ") { - continue - } - lines = append(lines, l) - } - return lines -} - -func TestCopiedCodeInSync(t *testing.T) { - // Until we drop Go 1.8 support, we need to keep a near-exact copy of the - // ztest package's WriteSyncer test spies in zaptest. This test ensures that - // the two files stay in sync. - assert.Equal(t, - readCode(t, "../internal/ztest/writer.go"), - readCode(t, "writer.go"), - "Writer spy implementations in zaptest and internal/ztest should be identical.", - ) -} - func TestSyncer(t *testing.T) { err := errors.New("sentinel") s := &Syncer{} From de399f14f0569bd5218e49e4b388da1748e65445 Mon Sep 17 00:00:00 2001 From: Akshay Shah Date: Fri, 13 Apr 2018 13:25:07 -0700 Subject: [PATCH 3/4] Add an alias for zapcore.Field The `Field` union struct is defined in `zapcore`, but most of its constructors are in the top-level `zap` package. This makes the zap GoDoc really unfriendly, since the field constructors are mixed in with other top-level functions instead of being grouped together under the field type. This commit adds a `zap.Field` type which is just an alias for `zapcore.Field`. It then changes all the top-level zap code to use the alias. For validation, this commit leaves all test code unchanged. --- array.go | 46 +++++++++++----------- config.go | 2 +- error.go | 6 +-- field.go | 110 +++++++++++++++++++++++++++-------------------------- global.go | 4 +- logger.go | 16 ++++---- options.go | 2 +- sugar.go | 12 +++--- 8 files changed, 101 insertions(+), 97 deletions(-) diff --git a/array.go b/array.go index 3d4d49f47..5be3704a3 100644 --- a/array.go +++ b/array.go @@ -29,113 +29,113 @@ import ( // Array constructs a field with the given key and ArrayMarshaler. It provides // a flexible, but still type-safe and efficient, way to add array-like types // to the logging context. The struct's MarshalLogArray method is called lazily. -func Array(key string, val zapcore.ArrayMarshaler) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.ArrayMarshalerType, Interface: val} +func Array(key string, val zapcore.ArrayMarshaler) Field { + return Field{Key: key, Type: zapcore.ArrayMarshalerType, Interface: val} } // Bools constructs a field that carries a slice of bools. -func Bools(key string, bs []bool) zapcore.Field { +func Bools(key string, bs []bool) Field { return Array(key, bools(bs)) } // ByteStrings constructs a field that carries a slice of []byte, each of which // must be UTF-8 encoded text. -func ByteStrings(key string, bss [][]byte) zapcore.Field { +func ByteStrings(key string, bss [][]byte) Field { return Array(key, byteStringsArray(bss)) } // Complex128s constructs a field that carries a slice of complex numbers. -func Complex128s(key string, nums []complex128) zapcore.Field { +func Complex128s(key string, nums []complex128) Field { return Array(key, complex128s(nums)) } // Complex64s constructs a field that carries a slice of complex numbers. -func Complex64s(key string, nums []complex64) zapcore.Field { +func Complex64s(key string, nums []complex64) Field { return Array(key, complex64s(nums)) } // Durations constructs a field that carries a slice of time.Durations. -func Durations(key string, ds []time.Duration) zapcore.Field { +func Durations(key string, ds []time.Duration) Field { return Array(key, durations(ds)) } // Float64s constructs a field that carries a slice of floats. -func Float64s(key string, nums []float64) zapcore.Field { +func Float64s(key string, nums []float64) Field { return Array(key, float64s(nums)) } // Float32s constructs a field that carries a slice of floats. -func Float32s(key string, nums []float32) zapcore.Field { +func Float32s(key string, nums []float32) Field { return Array(key, float32s(nums)) } // Ints constructs a field that carries a slice of integers. -func Ints(key string, nums []int) zapcore.Field { +func Ints(key string, nums []int) Field { return Array(key, ints(nums)) } // Int64s constructs a field that carries a slice of integers. -func Int64s(key string, nums []int64) zapcore.Field { +func Int64s(key string, nums []int64) Field { return Array(key, int64s(nums)) } // Int32s constructs a field that carries a slice of integers. -func Int32s(key string, nums []int32) zapcore.Field { +func Int32s(key string, nums []int32) Field { return Array(key, int32s(nums)) } // Int16s constructs a field that carries a slice of integers. -func Int16s(key string, nums []int16) zapcore.Field { +func Int16s(key string, nums []int16) Field { return Array(key, int16s(nums)) } // Int8s constructs a field that carries a slice of integers. -func Int8s(key string, nums []int8) zapcore.Field { +func Int8s(key string, nums []int8) Field { return Array(key, int8s(nums)) } // Strings constructs a field that carries a slice of strings. -func Strings(key string, ss []string) zapcore.Field { +func Strings(key string, ss []string) Field { return Array(key, stringArray(ss)) } // Times constructs a field that carries a slice of time.Times. -func Times(key string, ts []time.Time) zapcore.Field { +func Times(key string, ts []time.Time) Field { return Array(key, times(ts)) } // Uints constructs a field that carries a slice of unsigned integers. -func Uints(key string, nums []uint) zapcore.Field { +func Uints(key string, nums []uint) Field { return Array(key, uints(nums)) } // Uint64s constructs a field that carries a slice of unsigned integers. -func Uint64s(key string, nums []uint64) zapcore.Field { +func Uint64s(key string, nums []uint64) Field { return Array(key, uint64s(nums)) } // Uint32s constructs a field that carries a slice of unsigned integers. -func Uint32s(key string, nums []uint32) zapcore.Field { +func Uint32s(key string, nums []uint32) Field { return Array(key, uint32s(nums)) } // Uint16s constructs a field that carries a slice of unsigned integers. -func Uint16s(key string, nums []uint16) zapcore.Field { +func Uint16s(key string, nums []uint16) Field { return Array(key, uint16s(nums)) } // Uint8s constructs a field that carries a slice of unsigned integers. -func Uint8s(key string, nums []uint8) zapcore.Field { +func Uint8s(key string, nums []uint8) Field { return Array(key, uint8s(nums)) } // Uintptrs constructs a field that carries a slice of pointer addresses. -func Uintptrs(key string, us []uintptr) zapcore.Field { +func Uintptrs(key string, us []uintptr) Field { return Array(key, uintptrs(us)) } // Errors constructs a field that carries a slice of errors. -func Errors(key string, errs []error) zapcore.Field { +func Errors(key string, errs []error) Field { return Array(key, errArray(errs)) } diff --git a/config.go b/config.go index b0658eda0..dae130303 100644 --- a/config.go +++ b/config.go @@ -210,7 +210,7 @@ func (cfg Config) buildOptions(errSink zapcore.WriteSyncer) []Option { } if len(cfg.InitialFields) > 0 { - fs := make([]zapcore.Field, 0, len(cfg.InitialFields)) + fs := make([]Field, 0, len(cfg.InitialFields)) keys := make([]string, 0, len(cfg.InitialFields)) for k := range cfg.InitialFields { keys = append(keys, k) diff --git a/error.go b/error.go index 2bff30d85..65982a51e 100644 --- a/error.go +++ b/error.go @@ -31,7 +31,7 @@ var _errArrayElemPool = sync.Pool{New: func() interface{} { }} // Error is shorthand for the common idiom NamedError("error", err). -func Error(err error) zapcore.Field { +func Error(err error) Field { return NamedError("error", err) } @@ -42,11 +42,11 @@ func Error(err error) zapcore.Field { // // For the common case in which the key is simply "error", the Error function // is shorter and less repetitive. -func NamedError(key string, err error) zapcore.Field { +func NamedError(key string, err error) Field { if err == nil { return Skip() } - return zapcore.Field{Key: key, Type: zapcore.ErrorType, Interface: err} + return Field{Key: key, Type: zapcore.ErrorType, Interface: err} } type errArray []error diff --git a/field.go b/field.go index 334740844..5130e1347 100644 --- a/field.go +++ b/field.go @@ -28,10 +28,14 @@ import ( "go.uber.org/zap/zapcore" ) +// Field is an alias for Field. Aliasing this type dramatically +// improves the navigability of this package's API documentation. +type Field = zapcore.Field + // Skip constructs a no-op field, which is often useful when handling invalid // inputs in other Field constructors. -func Skip() zapcore.Field { - return zapcore.Field{Type: zapcore.SkipType} +func Skip() Field { + return Field{Type: zapcore.SkipType} } // Binary constructs a field that carries an opaque binary blob. @@ -39,112 +43,112 @@ func Skip() zapcore.Field { // Binary data is serialized in an encoding-appropriate format. For example, // zap's JSON encoder base64-encodes binary blobs. To log UTF-8 encoded text, // use ByteString. -func Binary(key string, val []byte) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.BinaryType, Interface: val} +func Binary(key string, val []byte) Field { + return Field{Key: key, Type: zapcore.BinaryType, Interface: val} } // Bool constructs a field that carries a bool. -func Bool(key string, val bool) zapcore.Field { +func Bool(key string, val bool) Field { var ival int64 if val { ival = 1 } - return zapcore.Field{Key: key, Type: zapcore.BoolType, Integer: ival} + return Field{Key: key, Type: zapcore.BoolType, Integer: ival} } // ByteString constructs a field that carries UTF-8 encoded text as a []byte. // To log opaque binary blobs (which aren't necessarily valid UTF-8), use // Binary. -func ByteString(key string, val []byte) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.ByteStringType, Interface: val} +func ByteString(key string, val []byte) Field { + return Field{Key: key, Type: zapcore.ByteStringType, Interface: val} } // Complex128 constructs a field that carries a complex number. Unlike most // numeric fields, this costs an allocation (to convert the complex128 to // interface{}). -func Complex128(key string, val complex128) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Complex128Type, Interface: val} +func Complex128(key string, val complex128) Field { + return Field{Key: key, Type: zapcore.Complex128Type, Interface: val} } // Complex64 constructs a field that carries a complex number. Unlike most // numeric fields, this costs an allocation (to convert the complex64 to // interface{}). -func Complex64(key string, val complex64) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Complex64Type, Interface: val} +func Complex64(key string, val complex64) Field { + return Field{Key: key, Type: zapcore.Complex64Type, Interface: val} } // Float64 constructs a field that carries a float64. The way the // floating-point value is represented is encoder-dependent, so marshaling is // necessarily lazy. -func Float64(key string, val float64) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Float64Type, Integer: int64(math.Float64bits(val))} +func Float64(key string, val float64) Field { + return Field{Key: key, Type: zapcore.Float64Type, Integer: int64(math.Float64bits(val))} } // Float32 constructs a field that carries a float32. The way the // floating-point value is represented is encoder-dependent, so marshaling is // necessarily lazy. -func Float32(key string, val float32) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Float32Type, Integer: int64(math.Float32bits(val))} +func Float32(key string, val float32) Field { + return Field{Key: key, Type: zapcore.Float32Type, Integer: int64(math.Float32bits(val))} } // Int constructs a field with the given key and value. -func Int(key string, val int) zapcore.Field { +func Int(key string, val int) Field { return Int64(key, int64(val)) } // Int64 constructs a field with the given key and value. -func Int64(key string, val int64) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Int64Type, Integer: val} +func Int64(key string, val int64) Field { + return Field{Key: key, Type: zapcore.Int64Type, Integer: val} } // Int32 constructs a field with the given key and value. -func Int32(key string, val int32) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Int32Type, Integer: int64(val)} +func Int32(key string, val int32) Field { + return Field{Key: key, Type: zapcore.Int32Type, Integer: int64(val)} } // Int16 constructs a field with the given key and value. -func Int16(key string, val int16) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Int16Type, Integer: int64(val)} +func Int16(key string, val int16) Field { + return Field{Key: key, Type: zapcore.Int16Type, Integer: int64(val)} } // Int8 constructs a field with the given key and value. -func Int8(key string, val int8) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Int8Type, Integer: int64(val)} +func Int8(key string, val int8) Field { + return Field{Key: key, Type: zapcore.Int8Type, Integer: int64(val)} } // String constructs a field with the given key and value. -func String(key string, val string) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.StringType, String: val} +func String(key string, val string) Field { + return Field{Key: key, Type: zapcore.StringType, String: val} } // Uint constructs a field with the given key and value. -func Uint(key string, val uint) zapcore.Field { +func Uint(key string, val uint) Field { return Uint64(key, uint64(val)) } // Uint64 constructs a field with the given key and value. -func Uint64(key string, val uint64) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Uint64Type, Integer: int64(val)} +func Uint64(key string, val uint64) Field { + return Field{Key: key, Type: zapcore.Uint64Type, Integer: int64(val)} } // Uint32 constructs a field with the given key and value. -func Uint32(key string, val uint32) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Uint32Type, Integer: int64(val)} +func Uint32(key string, val uint32) Field { + return Field{Key: key, Type: zapcore.Uint32Type, Integer: int64(val)} } // Uint16 constructs a field with the given key and value. -func Uint16(key string, val uint16) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Uint16Type, Integer: int64(val)} +func Uint16(key string, val uint16) Field { + return Field{Key: key, Type: zapcore.Uint16Type, Integer: int64(val)} } // Uint8 constructs a field with the given key and value. -func Uint8(key string, val uint8) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.Uint8Type, Integer: int64(val)} +func Uint8(key string, val uint8) Field { + return Field{Key: key, Type: zapcore.Uint8Type, Integer: int64(val)} } // Uintptr constructs a field with the given key and value. -func Uintptr(key string, val uintptr) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.UintptrType, Integer: int64(val)} +func Uintptr(key string, val uintptr) Field { + return Field{Key: key, Type: zapcore.UintptrType, Integer: int64(val)} } // Reflect constructs a field with the given key and an arbitrary object. It uses @@ -154,8 +158,8 @@ func Uintptr(key string, val uintptr) zapcore.Field { // // If encoding fails (e.g., trying to serialize a map[int]string to JSON), Reflect // includes the error message in the final log output. -func Reflect(key string, val interface{}) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.ReflectType, Interface: val} +func Reflect(key string, val interface{}) Field { + return Field{Key: key, Type: zapcore.ReflectType, Interface: val} } // Namespace creates a named, isolated scope within the logger's context. All @@ -163,27 +167,27 @@ func Reflect(key string, val interface{}) zapcore.Field { // // This helps prevent key collisions when injecting loggers into sub-components // or third-party libraries. -func Namespace(key string) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.NamespaceType} +func Namespace(key string) Field { + return Field{Key: key, Type: zapcore.NamespaceType} } // Stringer constructs a field with the given key and the output of the value's // String method. The Stringer's String method is called lazily. -func Stringer(key string, val fmt.Stringer) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.StringerType, Interface: val} +func Stringer(key string, val fmt.Stringer) Field { + return Field{Key: key, Type: zapcore.StringerType, Interface: val} } -// Time constructs a zapcore.Field with the given key and value. The encoder +// Time constructs a Field with the given key and value. The encoder // controls how the time is serialized. -func Time(key string, val time.Time) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.TimeType, Integer: val.UnixNano(), Interface: val.Location()} +func Time(key string, val time.Time) Field { + return Field{Key: key, Type: zapcore.TimeType, Integer: val.UnixNano(), Interface: val.Location()} } // Stack constructs a field that stores a stacktrace of the current goroutine // under provided key. Keep in mind that taking a stacktrace is eager and // expensive (relatively speaking); this function both makes an allocation and // takes about two microseconds. -func Stack(key string) zapcore.Field { +func Stack(key string) Field { // Returning the stacktrace as a string costs an allocation, but saves us // from expanding the zapcore.Field union struct to include a byte slice. Since // taking a stacktrace is already so expensive (~10us), the extra allocation @@ -193,16 +197,16 @@ func Stack(key string) zapcore.Field { // Duration constructs a field with the given key and value. The encoder // controls how the duration is serialized. -func Duration(key string, val time.Duration) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.DurationType, Integer: int64(val)} +func Duration(key string, val time.Duration) Field { + return Field{Key: key, Type: zapcore.DurationType, Integer: int64(val)} } // Object constructs a field with the given key and ObjectMarshaler. It // provides a flexible, but still type-safe and efficient, way to add map- or // struct-like user-defined types to the logging context. The struct's // MarshalLogObject method is called lazily. -func Object(key string, val zapcore.ObjectMarshaler) zapcore.Field { - return zapcore.Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val} +func Object(key string, val zapcore.ObjectMarshaler) Field { + return Field{Key: key, Type: zapcore.ObjectMarshalerType, Interface: val} } // Any takes a key and an arbitrary value and chooses the best way to represent @@ -212,7 +216,7 @@ func Object(key string, val zapcore.ObjectMarshaler) zapcore.Field { // Since byte/uint8 and rune/int32 are aliases, Any can't differentiate between // them. To minimize surprises, []byte values are treated as binary blobs, byte // values are treated as uint8, and runes are always treated as integers. -func Any(key string, value interface{}) zapcore.Field { +func Any(key string, value interface{}) Field { switch val := value.(type) { case zapcore.ObjectMarshaler: return Object(key, val) diff --git a/global.go b/global.go index 7c9a6747a..d02232e39 100644 --- a/global.go +++ b/global.go @@ -138,7 +138,7 @@ func redirectStdLogAt(l *Logger, level zapcore.Level) (func(), error) { }, nil } -func levelToFunc(logger *Logger, lvl zapcore.Level) (func(string, ...zapcore.Field), error) { +func levelToFunc(logger *Logger, lvl zapcore.Level) (func(string, ...Field), error) { switch lvl { case DebugLevel: return logger.Debug, nil @@ -159,7 +159,7 @@ func levelToFunc(logger *Logger, lvl zapcore.Level) (func(string, ...zapcore.Fie } type loggerWriter struct { - logFunc func(msg string, fields ...zapcore.Field) + logFunc func(msg string, fields ...Field) } func (l *loggerWriter) Write(p []byte) (int, error) { diff --git a/logger.go b/logger.go index 7d8824b48..dc8f6e3a4 100644 --- a/logger.go +++ b/logger.go @@ -156,7 +156,7 @@ func (log *Logger) WithOptions(opts ...Option) *Logger { // With creates a child logger and adds structured context to it. Fields added // to the child don't affect the parent, and vice versa. -func (log *Logger) With(fields ...zapcore.Field) *Logger { +func (log *Logger) With(fields ...Field) *Logger { if len(fields) == 0 { return log } @@ -174,7 +174,7 @@ func (log *Logger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // Debug logs a message at DebugLevel. The message includes any fields passed // at the log site, as well as any fields accumulated on the logger. -func (log *Logger) Debug(msg string, fields ...zapcore.Field) { +func (log *Logger) Debug(msg string, fields ...Field) { if ce := log.check(DebugLevel, msg); ce != nil { ce.Write(fields...) } @@ -182,7 +182,7 @@ func (log *Logger) Debug(msg string, fields ...zapcore.Field) { // Info logs a message at InfoLevel. The message includes any fields passed // at the log site, as well as any fields accumulated on the logger. -func (log *Logger) Info(msg string, fields ...zapcore.Field) { +func (log *Logger) Info(msg string, fields ...Field) { if ce := log.check(InfoLevel, msg); ce != nil { ce.Write(fields...) } @@ -190,7 +190,7 @@ func (log *Logger) Info(msg string, fields ...zapcore.Field) { // Warn logs a message at WarnLevel. The message includes any fields passed // at the log site, as well as any fields accumulated on the logger. -func (log *Logger) Warn(msg string, fields ...zapcore.Field) { +func (log *Logger) Warn(msg string, fields ...Field) { if ce := log.check(WarnLevel, msg); ce != nil { ce.Write(fields...) } @@ -198,7 +198,7 @@ func (log *Logger) Warn(msg string, fields ...zapcore.Field) { // Error logs a message at ErrorLevel. The message includes any fields passed // at the log site, as well as any fields accumulated on the logger. -func (log *Logger) Error(msg string, fields ...zapcore.Field) { +func (log *Logger) Error(msg string, fields ...Field) { if ce := log.check(ErrorLevel, msg); ce != nil { ce.Write(fields...) } @@ -210,7 +210,7 @@ func (log *Logger) Error(msg string, fields ...zapcore.Field) { // If the logger is in development mode, it then panics (DPanic means // "development panic"). This is useful for catching errors that are // recoverable, but shouldn't ever happen. -func (log *Logger) DPanic(msg string, fields ...zapcore.Field) { +func (log *Logger) DPanic(msg string, fields ...Field) { if ce := log.check(DPanicLevel, msg); ce != nil { ce.Write(fields...) } @@ -220,7 +220,7 @@ func (log *Logger) DPanic(msg string, fields ...zapcore.Field) { // at the log site, as well as any fields accumulated on the logger. // // The logger then panics, even if logging at PanicLevel is disabled. -func (log *Logger) Panic(msg string, fields ...zapcore.Field) { +func (log *Logger) Panic(msg string, fields ...Field) { if ce := log.check(PanicLevel, msg); ce != nil { ce.Write(fields...) } @@ -231,7 +231,7 @@ func (log *Logger) Panic(msg string, fields ...zapcore.Field) { // // The logger then calls os.Exit(1), even if logging at FatalLevel is // disabled. -func (log *Logger) Fatal(msg string, fields ...zapcore.Field) { +func (log *Logger) Fatal(msg string, fields ...Field) { if ce := log.check(FatalLevel, msg); ce != nil { ce.Write(fields...) } diff --git a/options.go b/options.go index d0f9422d0..7a6b0fca1 100644 --- a/options.go +++ b/options.go @@ -55,7 +55,7 @@ func Hooks(hooks ...func(zapcore.Entry) error) Option { } // Fields adds fields to the Logger. -func Fields(fs ...zapcore.Field) Option { +func Fields(fs ...Field) Option { return optionFunc(func(log *Logger) { log.core = log.core.With(fs) }) diff --git a/sugar.go b/sugar.go index 9cda00962..77ca227f4 100644 --- a/sugar.go +++ b/sugar.go @@ -62,9 +62,9 @@ func (s *SugaredLogger) Named(name string) *SugaredLogger { } // With adds a variadic number of fields to the logging context. It accepts a -// mix of strongly-typed zapcore.Field objects and loosely-typed key-value -// pairs. When processing pairs, the first element of the pair is used as the -// field key and the second as the field value. +// mix of strongly-typed Field objects and loosely-typed key-value pairs. When +// processing pairs, the first element of the pair is used as the field key +// and the second as the field value. // // For example, // sugaredLogger.With( @@ -235,19 +235,19 @@ func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interf } } -func (s *SugaredLogger) sweetenFields(args []interface{}) []zapcore.Field { +func (s *SugaredLogger) sweetenFields(args []interface{}) []Field { if len(args) == 0 { return nil } // Allocate enough space for the worst case; if users pass only structured // fields, we shouldn't penalize them with extra allocations. - fields := make([]zapcore.Field, 0, len(args)) + fields := make([]Field, 0, len(args)) var invalid invalidPairs for i := 0; i < len(args); { // This is a strongly-typed field. Consume it and move on. - if f, ok := args[i].(zapcore.Field); ok { + if f, ok := args[i].(Field); ok { fields = append(fields, f) i++ continue From 3b4fd3387a418af17716157fe80c69b50b710ef6 Mon Sep 17 00:00:00 2001 From: Akshay Shah Date: Fri, 13 Apr 2018 13:27:25 -0700 Subject: [PATCH 4/4] Update tests to use zap.Field alias Update zap's tests to use the new `zap.Field` alias. Keeping this change in a separate commit lets us verify that changing to an alias is backward-compatible for callers. --- array_test.go | 2 +- benchmarks/zap_test.go | 4 +-- error_test.go | 10 ++++---- field_test.go | 58 +++++++++++++++++++++--------------------- global_test.go | 8 +++--- logger_bench_test.go | 4 +-- logger_test.go | 16 ++++++------ sugar_test.go | 40 ++++++++++++++--------------- 8 files changed, 71 insertions(+), 71 deletions(-) diff --git a/array_test.go b/array_test.go index df84d9213..54116dfbb 100644 --- a/array_test.go +++ b/array_test.go @@ -52,7 +52,7 @@ func BenchmarkBoolsReflect(b *testing.B) { func TestArrayWrappers(t *testing.T) { tests := []struct { desc string - field zapcore.Field + field Field expected []interface{} }{ {"empty bools", Bools("", []bool{}), []interface{}(nil)}, diff --git a/benchmarks/zap_test.go b/benchmarks/zap_test.go index dfb0d1396..92f7120ec 100644 --- a/benchmarks/zap_test.go +++ b/benchmarks/zap_test.go @@ -124,8 +124,8 @@ func newSampledLogger(lvl zapcore.Level) *zap.Logger { )) } -func fakeFields() []zapcore.Field { - return []zapcore.Field{ +func fakeFields() []zap.Field { + return []zap.Field{ zap.Int("int", _tenInts[0]), zap.Ints("ints", _tenInts), zap.String("string", _tenStrings[0]), diff --git a/error_test.go b/error_test.go index 54ce4bbd7..ad3418002 100644 --- a/error_test.go +++ b/error_test.go @@ -36,13 +36,13 @@ func TestErrorConstructors(t *testing.T) { tests := []struct { name string - field zapcore.Field - expect zapcore.Field + field Field + expect Field }{ {"Error", Skip(), Error(nil)}, - {"Error", zapcore.Field{Key: "error", Type: zapcore.ErrorType, Interface: fail}, Error(fail)}, + {"Error", Field{Key: "error", Type: zapcore.ErrorType, Interface: fail}, Error(fail)}, {"NamedError", Skip(), NamedError("foo", nil)}, - {"NamedError", zapcore.Field{Key: "foo", Type: zapcore.ErrorType, Interface: fail}, NamedError("foo", fail)}, + {"NamedError", Field{Key: "foo", Type: zapcore.ErrorType, Interface: fail}, NamedError("foo", fail)}, {"Any:Error", Any("k", errors.New("v")), NamedError("k", errors.New("v"))}, {"Any:Errors", Any("k", []error{errors.New("v")}), Errors("k", []error{errors.New("v")})}, } @@ -58,7 +58,7 @@ func TestErrorConstructors(t *testing.T) { func TestErrorArrayConstructor(t *testing.T) { tests := []struct { desc string - field zapcore.Field + field Field expected []interface{} }{ {"empty errors", Errors("", []error{}), []interface{}(nil)}, diff --git a/field_test.go b/field_test.go index c13922cd3..069bfe372 100644 --- a/field_test.go +++ b/field_test.go @@ -37,7 +37,7 @@ func (n username) MarshalLogObject(enc zapcore.ObjectEncoder) error { return nil } -func assertCanBeReused(t testing.TB, field zapcore.Field) { +func assertCanBeReused(t testing.TB, field Field) { var wg sync.WaitGroup for i := 0; i < 100; i++ { @@ -65,34 +65,34 @@ func TestFieldConstructors(t *testing.T) { tests := []struct { name string - field zapcore.Field - expect zapcore.Field + field Field + expect Field }{ - {"Skip", zapcore.Field{Type: zapcore.SkipType}, Skip()}, - {"Binary", zapcore.Field{Key: "k", Type: zapcore.BinaryType, Interface: []byte("ab12")}, Binary("k", []byte("ab12"))}, - {"Bool", zapcore.Field{Key: "k", Type: zapcore.BoolType, Integer: 1}, Bool("k", true)}, - {"Bool", zapcore.Field{Key: "k", Type: zapcore.BoolType, Integer: 1}, Bool("k", true)}, - {"ByteString", zapcore.Field{Key: "k", Type: zapcore.ByteStringType, Interface: []byte("ab12")}, ByteString("k", []byte("ab12"))}, - {"Complex128", zapcore.Field{Key: "k", Type: zapcore.Complex128Type, Interface: 1 + 2i}, Complex128("k", 1+2i)}, - {"Complex64", zapcore.Field{Key: "k", Type: zapcore.Complex64Type, Interface: complex64(1 + 2i)}, Complex64("k", 1+2i)}, - {"Duration", zapcore.Field{Key: "k", Type: zapcore.DurationType, Integer: 1}, Duration("k", 1)}, - {"Int", zapcore.Field{Key: "k", Type: zapcore.Int64Type, Integer: 1}, Int("k", 1)}, - {"Int64", zapcore.Field{Key: "k", Type: zapcore.Int64Type, Integer: 1}, Int64("k", 1)}, - {"Int32", zapcore.Field{Key: "k", Type: zapcore.Int32Type, Integer: 1}, Int32("k", 1)}, - {"Int16", zapcore.Field{Key: "k", Type: zapcore.Int16Type, Integer: 1}, Int16("k", 1)}, - {"Int8", zapcore.Field{Key: "k", Type: zapcore.Int8Type, Integer: 1}, Int8("k", 1)}, - {"String", zapcore.Field{Key: "k", Type: zapcore.StringType, String: "foo"}, String("k", "foo")}, - {"Time", zapcore.Field{Key: "k", Type: zapcore.TimeType, Integer: 0, Interface: time.UTC}, Time("k", time.Unix(0, 0).In(time.UTC))}, - {"Time", zapcore.Field{Key: "k", Type: zapcore.TimeType, Integer: 1000, Interface: time.UTC}, Time("k", time.Unix(0, 1000).In(time.UTC))}, - {"Uint", zapcore.Field{Key: "k", Type: zapcore.Uint64Type, Integer: 1}, Uint("k", 1)}, - {"Uint64", zapcore.Field{Key: "k", Type: zapcore.Uint64Type, Integer: 1}, Uint64("k", 1)}, - {"Uint32", zapcore.Field{Key: "k", Type: zapcore.Uint32Type, Integer: 1}, Uint32("k", 1)}, - {"Uint16", zapcore.Field{Key: "k", Type: zapcore.Uint16Type, Integer: 1}, Uint16("k", 1)}, - {"Uint8", zapcore.Field{Key: "k", Type: zapcore.Uint8Type, Integer: 1}, Uint8("k", 1)}, - {"Uintptr", zapcore.Field{Key: "k", Type: zapcore.UintptrType, Integer: 10}, Uintptr("k", 0xa)}, - {"Reflect", zapcore.Field{Key: "k", Type: zapcore.ReflectType, Interface: ints}, Reflect("k", ints)}, - {"Stringer", zapcore.Field{Key: "k", Type: zapcore.StringerType, Interface: addr}, Stringer("k", addr)}, - {"Object", zapcore.Field{Key: "k", Type: zapcore.ObjectMarshalerType, Interface: name}, Object("k", name)}, + {"Skip", Field{Type: zapcore.SkipType}, Skip()}, + {"Binary", Field{Key: "k", Type: zapcore.BinaryType, Interface: []byte("ab12")}, Binary("k", []byte("ab12"))}, + {"Bool", Field{Key: "k", Type: zapcore.BoolType, Integer: 1}, Bool("k", true)}, + {"Bool", Field{Key: "k", Type: zapcore.BoolType, Integer: 1}, Bool("k", true)}, + {"ByteString", Field{Key: "k", Type: zapcore.ByteStringType, Interface: []byte("ab12")}, ByteString("k", []byte("ab12"))}, + {"Complex128", Field{Key: "k", Type: zapcore.Complex128Type, Interface: 1 + 2i}, Complex128("k", 1+2i)}, + {"Complex64", Field{Key: "k", Type: zapcore.Complex64Type, Interface: complex64(1 + 2i)}, Complex64("k", 1+2i)}, + {"Duration", Field{Key: "k", Type: zapcore.DurationType, Integer: 1}, Duration("k", 1)}, + {"Int", Field{Key: "k", Type: zapcore.Int64Type, Integer: 1}, Int("k", 1)}, + {"Int64", Field{Key: "k", Type: zapcore.Int64Type, Integer: 1}, Int64("k", 1)}, + {"Int32", Field{Key: "k", Type: zapcore.Int32Type, Integer: 1}, Int32("k", 1)}, + {"Int16", Field{Key: "k", Type: zapcore.Int16Type, Integer: 1}, Int16("k", 1)}, + {"Int8", Field{Key: "k", Type: zapcore.Int8Type, Integer: 1}, Int8("k", 1)}, + {"String", Field{Key: "k", Type: zapcore.StringType, String: "foo"}, String("k", "foo")}, + {"Time", Field{Key: "k", Type: zapcore.TimeType, Integer: 0, Interface: time.UTC}, Time("k", time.Unix(0, 0).In(time.UTC))}, + {"Time", Field{Key: "k", Type: zapcore.TimeType, Integer: 1000, Interface: time.UTC}, Time("k", time.Unix(0, 1000).In(time.UTC))}, + {"Uint", Field{Key: "k", Type: zapcore.Uint64Type, Integer: 1}, Uint("k", 1)}, + {"Uint64", Field{Key: "k", Type: zapcore.Uint64Type, Integer: 1}, Uint64("k", 1)}, + {"Uint32", Field{Key: "k", Type: zapcore.Uint32Type, Integer: 1}, Uint32("k", 1)}, + {"Uint16", Field{Key: "k", Type: zapcore.Uint16Type, Integer: 1}, Uint16("k", 1)}, + {"Uint8", Field{Key: "k", Type: zapcore.Uint8Type, Integer: 1}, Uint8("k", 1)}, + {"Uintptr", Field{Key: "k", Type: zapcore.UintptrType, Integer: 10}, Uintptr("k", 0xa)}, + {"Reflect", Field{Key: "k", Type: zapcore.ReflectType, Interface: ints}, Reflect("k", ints)}, + {"Stringer", Field{Key: "k", Type: zapcore.StringerType, Interface: addr}, Stringer("k", addr)}, + {"Object", Field{Key: "k", Type: zapcore.ObjectMarshalerType, Interface: name}, Object("k", name)}, {"Any:ObjectMarshaler", Any("k", name), Object("k", name)}, {"Any:ArrayMarshaler", Any("k", bools([]bool{true})), Array("k", bools([]bool{true}))}, {"Any:Stringer", Any("k", addr), Stringer("k", addr)}, @@ -139,7 +139,7 @@ func TestFieldConstructors(t *testing.T) { {"Any:Duration", Any("k", time.Second), Duration("k", time.Second)}, {"Any:Durations", Any("k", []time.Duration{time.Second}), Durations("k", []time.Duration{time.Second})}, {"Any:Fallback", Any("k", struct{}{}), Reflect("k", struct{}{})}, - {"Namespace", Namespace("k"), zapcore.Field{Key: "k", Type: zapcore.NamespaceType}}, + {"Namespace", Namespace("k"), Field{Key: "k", Type: zapcore.NamespaceType}}, } for _, tt := range tests { diff --git a/global_test.go b/global_test.go index 2627b3398..e169f5179 100644 --- a/global_test.go +++ b/global_test.go @@ -52,7 +52,7 @@ func TestReplaceGlobals(t *testing.T) { S().Info("captured") expected := observer.LoggedEntry{ Entry: zapcore.Entry{Message: "captured"}, - Context: []zapcore.Field{}, + Context: []Field{}, } assert.Equal( t, @@ -157,7 +157,7 @@ func TestRedirectStdLog(t *testing.T) { assert.Equal(t, []observer.LoggedEntry{{ Entry: zapcore.Entry{Message: "redirected"}, - Context: []zapcore.Field{}, + Context: []Field{}, }}, logs.AllUntimed(), "Unexpected global log output.") }) @@ -190,7 +190,7 @@ func TestRedirectStdLogAt(t *testing.T) { assert.Equal(t, []observer.LoggedEntry{{ Entry: zapcore.Entry{Level: level, Message: "redirected"}, - Context: []zapcore.Field{}, + Context: []Field{}, }}, logs.AllUntimed(), "Unexpected global log output.") }) } @@ -269,7 +269,7 @@ func TestRedirectStdLogAtInvalid(t *testing.T) { func checkStdLogMessage(t *testing.T, msg string, logs *observer.ObservedLogs) { require.Equal(t, 1, logs.Len(), "Expected exactly one entry to be logged") entry := logs.AllUntimed()[0] - assert.Equal(t, []zapcore.Field{}, entry.Context, "Unexpected entry context.") + assert.Equal(t, []Field{}, entry.Context, "Unexpected entry context.") assert.Equal(t, "redirected", entry.Entry.Message, "Unexpected entry message.") assert.Regexp( t, diff --git a/logger_bench_test.go b/logger_bench_test.go index 0247210c7..71c6b5911 100644 --- a/logger_bench_test.go +++ b/logger_bench_test.go @@ -207,8 +207,8 @@ func Benchmark100Fields(b *testing.B) { // Don't include allocating these helper slices in the benchmark. Since // access to them isn't synchronized, we can't run the benchmark in // parallel. - first := make([]zapcore.Field, batchSize) - second := make([]zapcore.Field, batchSize) + first := make([]Field, batchSize) + second := make([]Field, batchSize) b.ResetTimer() for i := 0; i < b.N; i++ { diff --git a/logger_test.go b/logger_test.go index f26555ccf..a9f705788 100644 --- a/logger_test.go +++ b/logger_test.go @@ -89,7 +89,7 @@ func TestLoggerInitialFields(t *testing.T) { logger.Info("") assert.Equal( t, - observer.LoggedEntry{Context: []zapcore.Field{Int("foo", 42), String("bar", "baz")}}, + observer.LoggedEntry{Context: []Field{Int("foo", 42), String("bar", "baz")}}, logs.AllUntimed()[0], "Unexpected output with initial fields set.", ) @@ -106,9 +106,9 @@ func TestLoggerWith(t *testing.T) { logger.Info("") assert.Equal(t, []observer.LoggedEntry{ - {Context: []zapcore.Field{Int("foo", 42), String("one", "two")}}, - {Context: []zapcore.Field{Int("foo", 42), String("three", "four")}}, - {Context: []zapcore.Field{Int("foo", 42)}}, + {Context: []Field{Int("foo", 42), String("one", "two")}}, + {Context: []Field{Int("foo", 42), String("three", "four")}}, + {Context: []Field{Int("foo", 42)}}, }, logs.AllUntimed(), "Unexpected cross-talk between child loggers.") }) } @@ -171,7 +171,7 @@ func TestLoggerLogFatal(t *testing.T) { func TestLoggerLeveledMethods(t *testing.T) { withLogger(t, DebugLevel, nil, func(logger *Logger, logs *observer.ObservedLogs) { tests := []struct { - method func(string, ...zapcore.Field) + method func(string, ...Field) expectedLevel zapcore.Level }{ {logger.Debug, DebugLevel}, @@ -232,7 +232,7 @@ func TestLoggerDPanic(t *testing.T) { assert.NotPanics(t, func() { logger.DPanic("") }) assert.Equal( t, - []observer.LoggedEntry{{Entry: zapcore.Entry{Level: DPanicLevel}, Context: []zapcore.Field{}}}, + []observer.LoggedEntry{{Entry: zapcore.Entry{Level: DPanicLevel}, Context: []Field{}}}, logs.AllUntimed(), "Unexpected log output from DPanic in production mode.", ) @@ -241,7 +241,7 @@ func TestLoggerDPanic(t *testing.T) { assert.Panics(t, func() { logger.DPanic("") }) assert.Equal( t, - []observer.LoggedEntry{{Entry: zapcore.Entry{Level: DPanicLevel}, Context: []zapcore.Field{}}}, + []observer.LoggedEntry{{Entry: zapcore.Entry{Level: DPanicLevel}, Context: []Field{}}}, logs.AllUntimed(), "Unexpected log output from DPanic in development mode.", ) @@ -422,7 +422,7 @@ func TestLoggerConcurrent(t *testing.T) { t, observer.LoggedEntry{ Entry: zapcore.Entry{Level: InfoLevel}, - Context: []zapcore.Field{String("foo", "bar")}, + Context: []Field{String("foo", "bar")}, }, obs, "Unexpected log output.", diff --git a/sugar_test.go b/sugar_test.go index a8353ca5d..5b1dcfacd 100644 --- a/sugar_test.go +++ b/sugar_test.go @@ -37,86 +37,86 @@ func TestSugarWith(t *testing.T) { ignored := func(msg interface{}) observer.LoggedEntry { return observer.LoggedEntry{ Entry: zapcore.Entry{Level: DPanicLevel, Message: _oddNumberErrMsg}, - Context: []zapcore.Field{Any("ignored", msg)}, + Context: []Field{Any("ignored", msg)}, } } nonString := func(pairs ...invalidPair) observer.LoggedEntry { return observer.LoggedEntry{ Entry: zapcore.Entry{Level: DPanicLevel, Message: _nonStringKeyErrMsg}, - Context: []zapcore.Field{Array("invalid", invalidPairs(pairs))}, + Context: []Field{Array("invalid", invalidPairs(pairs))}, } } tests := []struct { desc string args []interface{} - expected []zapcore.Field + expected []Field errLogs []observer.LoggedEntry }{ { desc: "nil args", args: nil, - expected: []zapcore.Field{}, + expected: []Field{}, errLogs: nil, }, { desc: "empty slice of args", args: []interface{}{}, - expected: []zapcore.Field{}, + expected: []Field{}, errLogs: nil, }, { desc: "just a dangling key", args: []interface{}{"should ignore"}, - expected: []zapcore.Field{}, + expected: []Field{}, errLogs: []observer.LoggedEntry{ignored("should ignore")}, }, { desc: "well-formed key-value pairs", args: []interface{}{"foo", 42, "true", "bar"}, - expected: []zapcore.Field{Int("foo", 42), String("true", "bar")}, + expected: []Field{Int("foo", 42), String("true", "bar")}, errLogs: nil, }, { desc: "just a structured field", args: []interface{}{Int("foo", 42)}, - expected: []zapcore.Field{Int("foo", 42)}, + expected: []Field{Int("foo", 42)}, errLogs: nil, }, { desc: "structured field and a dangling key", args: []interface{}{Int("foo", 42), "dangling"}, - expected: []zapcore.Field{Int("foo", 42)}, + expected: []Field{Int("foo", 42)}, errLogs: []observer.LoggedEntry{ignored("dangling")}, }, { desc: "structured field and a dangling non-string key", args: []interface{}{Int("foo", 42), 13}, - expected: []zapcore.Field{Int("foo", 42)}, + expected: []Field{Int("foo", 42)}, errLogs: []observer.LoggedEntry{ignored(13)}, }, { desc: "key-value pair and a dangling key", args: []interface{}{"foo", 42, "dangling"}, - expected: []zapcore.Field{Int("foo", 42)}, + expected: []Field{Int("foo", 42)}, errLogs: []observer.LoggedEntry{ignored("dangling")}, }, { desc: "pairs, a structured field, and a dangling key", args: []interface{}{"first", "field", Int("foo", 42), "baz", "quux", "dangling"}, - expected: []zapcore.Field{String("first", "field"), Int("foo", 42), String("baz", "quux")}, + expected: []Field{String("first", "field"), Int("foo", 42), String("baz", "quux")}, errLogs: []observer.LoggedEntry{ignored("dangling")}, }, { desc: "one non-string key", args: []interface{}{"foo", 42, true, "bar"}, - expected: []zapcore.Field{Int("foo", 42)}, + expected: []Field{Int("foo", 42)}, errLogs: []observer.LoggedEntry{nonString(invalidPair{2, true, "bar"})}, }, { desc: "pairs, structured fields, non-string keys, and a dangling key", args: []interface{}{"foo", 42, true, "bar", Int("structure", 11), 42, "reversed", "baz", "quux", "dangling"}, - expected: []zapcore.Field{Int("foo", 42), Int("structure", 11), String("baz", "quux")}, + expected: []Field{Int("foo", 42), Int("structure", 11), String("baz", "quux")}, errLogs: []observer.LoggedEntry{ ignored("dangling"), nonString(invalidPair{2, true, "bar"}, invalidPair{5, 42, "reversed"}), @@ -146,7 +146,7 @@ func TestSugarFieldsInvalidPairs(t *testing.T) { // Double-check that the actual message was logged. require.Equal(t, 2, len(output), "Unexpected number of entries logged.") - require.Equal(t, observer.LoggedEntry{Context: []zapcore.Field{}}, output[1], "Unexpected non-error log entry.") + require.Equal(t, observer.LoggedEntry{Context: []Field{}}, output[1], "Unexpected non-error log entry.") // Assert that the error message's structured fields serialize properly. require.Equal(t, 1, len(output[0].Context), "Expected one field in error entry context.") @@ -175,7 +175,7 @@ func TestSugarStructuredLogging(t *testing.T) { // Common to all test cases. context := []interface{}{"foo", "bar"} extra := []interface{}{"baz", false} - expectedFields := []zapcore.Field{String("foo", "bar"), Bool("baz", false)} + expectedFields := []Field{String("foo", "bar"), Bool("baz", false)} for _, tt := range tests { withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { @@ -207,7 +207,7 @@ func TestSugarConcatenatingLogging(t *testing.T) { // Common to all test cases. context := []interface{}{"foo", "bar"} - expectedFields := []zapcore.Field{String("foo", "bar")} + expectedFields := []Field{String("foo", "bar")} for _, tt := range tests { withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { @@ -243,7 +243,7 @@ func TestSugarTemplatedLogging(t *testing.T) { // Common to all test cases. context := []interface{}{"foo", "bar"} - expectedFields := []zapcore.Field{String("foo", "bar")} + expectedFields := []Field{String("foo", "bar")} for _, tt := range tests { withSugar(t, DebugLevel, nil, func(logger *SugaredLogger, logs *observer.ObservedLogs) { @@ -287,7 +287,7 @@ func TestSugarPanicLogging(t *testing.T) { assert.Panics(t, func() { tt.f(sugar) }, "Expected panic-level logger calls to panic.") if tt.expectedMsg != "" { assert.Equal(t, []observer.LoggedEntry{{ - Context: []zapcore.Field{}, + Context: []Field{}, Entry: zapcore.Entry{Message: tt.expectedMsg, Level: PanicLevel}, }}, logs.AllUntimed(), "Unexpected log output.") } else { @@ -320,7 +320,7 @@ func TestSugarFatalLogging(t *testing.T) { assert.True(t, stub.Exited, "Expected all calls to fatal logger methods to exit process.") if tt.expectedMsg != "" { assert.Equal(t, []observer.LoggedEntry{{ - Context: []zapcore.Field{}, + Context: []Field{}, Entry: zapcore.Entry{Message: tt.expectedMsg, Level: FatalLevel}, }}, logs.AllUntimed(), "Unexpected log output.") } else {