diff --git a/buffer/buffer.go b/buffer/buffer.go index 9e929cd98..23dd6de58 100644 --- a/buffer/buffer.go +++ b/buffer/buffer.go @@ -33,8 +33,8 @@ const _size = 1024 // by default, create 1 KiB buffers // Buffer is a thin wrapper around a byte slice. It's intended to be pooled, so // the only way to construct one is via a Pool. type Buffer struct { - bs []byte pool Pool + bs []byte } // AppendByte writes a single byte to the Buffer. diff --git a/config.go b/config.go index e76e4e64f..c7eece545 100644 --- a/config.go +++ b/config.go @@ -37,9 +37,9 @@ import ( // Values configured here are per-second. See zapcore.NewSamplerWithOptions for // details. type SamplingConfig struct { + Hook func(zapcore.Entry, zapcore.SamplingDecision) `json:"-" yaml:"-"` Initial int `json:"initial" yaml:"initial"` Thereafter int `json:"thereafter" yaml:"thereafter"` - Hook func(zapcore.Entry, zapcore.SamplingDecision) `json:"-" yaml:"-"` } // Config offers a declarative way to construct a logger. It doesn't do @@ -60,25 +60,17 @@ type Config struct { // level, so calling Config.Level.SetLevel will atomically change the log // level of all loggers descended from this config. Level AtomicLevel `json:"level" yaml:"level"` - // Development puts the logger in development mode, which changes the - // behavior of DPanicLevel and takes stacktraces more liberally. - Development bool `json:"development" yaml:"development"` - // DisableCaller stops annotating logs with the calling function's file - // name and line number. By default, all logs are annotated. - DisableCaller bool `json:"disableCaller" yaml:"disableCaller"` - // DisableStacktrace completely disables automatic stacktrace capturing. By - // default, stacktraces are captured for WarnLevel and above logs in - // development and ErrorLevel and above in production. - DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"` // Sampling sets a sampling policy. A nil SamplingConfig disables sampling. Sampling *SamplingConfig `json:"sampling" yaml:"sampling"` + // InitialFields is a collection of fields to add to the root logger. + InitialFields map[string]interface{} `json:"initialFields" yaml:"initialFields"` + // EncoderConfig sets options for the chosen encoder. See + // zapcore.EncoderConfig for details. + EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"` // Encoding sets the logger's encoding. Valid values are "json" and // "console", as well as any third-party encodings registered via // RegisterEncoder. Encoding string `json:"encoding" yaml:"encoding"` - // EncoderConfig sets options for the chosen encoder. See - // zapcore.EncoderConfig for details. - EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"` // OutputPaths is a list of URLs or file paths to write logging output to. // See Open for details. OutputPaths []string `json:"outputPaths" yaml:"outputPaths"` @@ -89,8 +81,16 @@ type Config struct { // sends error-level logs to a different location from info- and debug-level // logs, see the package-level AdvancedConfiguration example. ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"` - // InitialFields is a collection of fields to add to the root logger. - InitialFields map[string]interface{} `json:"initialFields" yaml:"initialFields"` + // Development puts the logger in development mode, which changes the + // behavior of DPanicLevel and takes stacktraces more liberally. + Development bool `json:"development" yaml:"development"` + // DisableCaller stops annotating logs with the calling function's file + // name and line number. By default, all logs are annotated. + DisableCaller bool `json:"disableCaller" yaml:"disableCaller"` + // DisableStacktrace completely disables automatic stacktrace capturing. By + // default, stacktraces are captured for WarnLevel and above logs in + // development and ErrorLevel and above in production. + DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"` } // NewProductionEncoderConfig returns an opinionated EncoderConfig for diff --git a/internal/exit/exit.go b/internal/exit/exit.go index f673f9947..890c0b67e 100644 --- a/internal/exit/exit.go +++ b/internal/exit/exit.go @@ -34,9 +34,9 @@ func With(code int) { // A StubbedExit is a testing fake for os.Exit. type StubbedExit struct { - Exited bool - Code int prev func(code int) + Code int + Exited bool } // Stub substitutes a fake for the call to os.Exit(1). diff --git a/internal/ztest/writer.go b/internal/ztest/writer.go index f54d8569e..f952a3577 100644 --- a/internal/ztest/writer.go +++ b/internal/ztest/writer.go @@ -79,8 +79,8 @@ func (w ShortWriter) Write(b []byte) (int, error) { // a bytes.Buffer. It has convenience methods to split the accumulated buffer // on newlines. type Buffer struct { - bytes.Buffer Syncer + bytes.Buffer } // Lines returns the current buffer contents, split on newlines. diff --git a/logger.go b/logger.go index 32d737276..34aff6b73 100644 --- a/logger.go +++ b/logger.go @@ -41,18 +41,20 @@ import ( type Logger struct { core zapcore.Core - development bool - addCaller bool - onFatal zapcore.CheckWriteHook // default is WriteThenFatal + onFatal zapcore.CheckWriteHook // default is WriteThenFatal - name string errorOutput zapcore.WriteSyncer addStack zapcore.LevelEnabler + clock zapcore.Clock + + name string + callerSkip int - clock zapcore.Clock + development bool + addCaller bool } // New constructs a new Logger from the provided zapcore.Core and Options. If diff --git a/sink.go b/sink.go index 478c9a10f..76521f988 100644 --- a/sink.go +++ b/sink.go @@ -56,9 +56,9 @@ type nopCloserSink struct{ zapcore.WriteSyncer } func (nopCloserSink) Close() error { return nil } type sinkRegistry struct { - mu sync.Mutex factories map[string]func(*url.URL) (Sink, error) // keyed by scheme openFile func(string, int, os.FileMode) (*os.File, error) // type matches os.OpenFile + mu sync.Mutex } func newSinkRegistry() *sinkRegistry { diff --git a/sugar.go b/sugar.go index 00ac5fe3a..6a405bca3 100644 --- a/sugar.go +++ b/sugar.go @@ -400,7 +400,7 @@ func (s *SugaredLogger) sweetenFields(args []interface{}) []Field { if cap(invalid) == 0 { invalid = make(invalidPairs, 0, len(args)/2) } - invalid = append(invalid, invalidPair{i, key, val}) + invalid = append(invalid, invalidPair{position: i, key: key, value: val}) } else { fields = append(fields, Any(keyStr, val)) } @@ -415,8 +415,8 @@ func (s *SugaredLogger) sweetenFields(args []interface{}) []Field { } type invalidPair struct { - position int key, value interface{} + position int } func (p invalidPair) MarshalLogObject(enc zapcore.ObjectEncoder) error { diff --git a/sugar_test.go b/sugar_test.go index 9e914ecf8..f6d13c0e4 100644 --- a/sugar_test.go +++ b/sugar_test.go @@ -118,7 +118,7 @@ func TestSugarWith(t *testing.T) { desc: "one non-string key", args: []interface{}{"foo", 42, true, "bar"}, expected: []Field{Int("foo", 42)}, - errLogs: []observer.LoggedEntry{nonString(invalidPair{2, true, "bar"})}, + errLogs: []observer.LoggedEntry{nonString(invalidPair{position: 2, key: true, value: "bar"})}, }, { desc: "pairs, structured fields, non-string keys, and a dangling key", @@ -126,7 +126,7 @@ func TestSugarWith(t *testing.T) { 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"}), + nonString(invalidPair{position: 2, key: true, value: "bar"}, invalidPair{position: 5, key: 42, value: "reversed"}), }, }, { diff --git a/zapcore/buffered_write_syncer.go b/zapcore/buffered_write_syncer.go index a40e93b3e..6c94b64a9 100644 --- a/zapcore/buffered_write_syncer.go +++ b/zapcore/buffered_write_syncer.go @@ -81,6 +81,17 @@ type BufferedWriteSyncer struct { // This field is required. WS WriteSyncer + // Clock, if specified, provides control of the source of time for the + // writer. + // + // Defaults to the system clock. + Clock Clock + + writer *bufio.Writer + ticker *time.Ticker + stop chan struct{} // closed when flushLoop should stop + done chan struct{} // closed when flushLoop has stopped + // Size specifies the maximum amount of data the writer will buffered // before flushing. // @@ -93,20 +104,10 @@ type BufferedWriteSyncer struct { // Defaults to 30 seconds if unspecified. FlushInterval time.Duration - // Clock, if specified, provides control of the source of time for the - // writer. - // - // Defaults to the system clock. - Clock Clock - // unexported fields for state mu sync.Mutex initialized bool // whether initialize() has run stopped bool // whether Stop() has run - writer *bufio.Writer - ticker *time.Ticker - stop chan struct{} // closed when flushLoop should stop - done chan struct{} // closed when flushLoop has stopped } func (s *BufferedWriteSyncer) initialize() { diff --git a/zapcore/encoder.go b/zapcore/encoder.go index 5769ff3e4..36b466bd9 100644 --- a/zapcore/encoder.go +++ b/zapcore/encoder.go @@ -314,17 +314,6 @@ func (e *NameEncoder) UnmarshalText(text []byte) error { // An EncoderConfig allows users to configure the concrete encoders supplied by // zapcore. type EncoderConfig struct { - // Set the keys used for each log entry. If any key is empty, that portion - // of the entry is omitted. - MessageKey string `json:"messageKey" yaml:"messageKey"` - LevelKey string `json:"levelKey" yaml:"levelKey"` - TimeKey string `json:"timeKey" yaml:"timeKey"` - NameKey string `json:"nameKey" yaml:"nameKey"` - CallerKey string `json:"callerKey" yaml:"callerKey"` - FunctionKey string `json:"functionKey" yaml:"functionKey"` - StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"` - SkipLineEnding bool `json:"skipLineEnding" yaml:"skipLineEnding"` - LineEnding string `json:"lineEnding" yaml:"lineEnding"` // Configure the primitive representations of common complex types. For // example, some users may want all time.Times serialized as floating-point // seconds since epoch, while others may prefer ISO8601 strings. @@ -338,9 +327,20 @@ type EncoderConfig struct { // Configure the encoder for interface{} type objects. // If not provided, objects are encoded using json.Encoder NewReflectedEncoder func(io.Writer) ReflectedEncoder `json:"-" yaml:"-"` + // Set the keys used for each log entry. If any key is empty, that portion + // of the entry is omitted. + MessageKey string `json:"messageKey" yaml:"messageKey"` + LevelKey string `json:"levelKey" yaml:"levelKey"` + TimeKey string `json:"timeKey" yaml:"timeKey"` + NameKey string `json:"nameKey" yaml:"nameKey"` + CallerKey string `json:"callerKey" yaml:"callerKey"` + FunctionKey string `json:"functionKey" yaml:"functionKey"` + StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"` + LineEnding string `json:"lineEnding" yaml:"lineEnding"` // Configures the field separator used by the console encoder. Defaults // to tab. ConsoleSeparator string `json:"consoleSeparator" yaml:"consoleSeparator"` + SkipLineEnding bool `json:"skipLineEnding" yaml:"skipLineEnding"` } // ObjectEncoder is a strongly-typed, encoding-agnostic interface for adding a diff --git a/zapcore/entry.go b/zapcore/entry.go index 059844f92..c8a566667 100644 --- a/zapcore/entry.go +++ b/zapcore/entry.go @@ -68,11 +68,11 @@ func NewEntryCaller(pc uintptr, file string, line int, ok bool) EntryCaller { // EntryCaller represents the caller of a logging function. type EntryCaller struct { - Defined bool - PC uintptr File string - Line int Function string + PC uintptr + Line int + Defined bool } // String returns the full path and line number of the caller. @@ -141,12 +141,12 @@ func (ec EntryCaller) TrimmedPath() string { // Entries are pooled, so any functions that accept them MUST be careful not to // retain references to them. type Entry struct { - Level Level Time time.Time + Caller EntryCaller LoggerName string Message string - Caller EntryCaller Stack string + Level Level } // CheckWriteHook is a custom action that may be executed after an entry is @@ -208,11 +208,11 @@ var _ CheckWriteHook = CheckWriteAction(0) // nil *CheckedEntry. References are returned to a pool after Write, and MUST // NOT be retained after calling their Write method. type CheckedEntry struct { - Entry ErrorOutput WriteSyncer - dirty bool // best-effort detection of pool misuse after CheckWriteHook - cores []Core + Entry + cores []Core + dirty bool // best-effort detection of pool misuse } func (ce *CheckedEntry) reset() { diff --git a/zapcore/field.go b/zapcore/field.go index 95bdb0a12..615d299fc 100644 --- a/zapcore/field.go +++ b/zapcore/field.go @@ -102,11 +102,11 @@ const ( // context. Most fields are lazily marshaled, so it's inexpensive to add fields // to disabled debug-level log statements. type Field struct { + Interface interface{} Key string - Type FieldType - Integer int64 String string - Interface interface{} + Integer int64 + Type FieldType } // AddTo exports a field through the ObjectEncoder interface. It's primarily diff --git a/zapcore/json_encoder.go b/zapcore/json_encoder.go index ce6838de2..5725451aa 100644 --- a/zapcore/json_encoder.go +++ b/zapcore/json_encoder.go @@ -52,14 +52,15 @@ func putJSONEncoder(enc *jsonEncoder) { } type jsonEncoder struct { + reflectEnc ReflectedEncoder *EncoderConfig - buf *buffer.Buffer - spaced bool // include spaces after colons and commas - openNamespaces int + buf *buffer.Buffer // for encoding generic values by reflection - reflectBuf *buffer.Buffer - reflectEnc ReflectedEncoder + reflectBuf *buffer.Buffer + openNamespaces int + + spaced bool // include spaces after colons and commas } // NewJSONEncoder creates a fast, low-allocation JSON encoder. The encoder diff --git a/zapcore/sampler.go b/zapcore/sampler.go index b7c093a4f..835716510 100644 --- a/zapcore/sampler.go +++ b/zapcore/sampler.go @@ -169,9 +169,9 @@ type sampler struct { Core counts *counters + hook func(Entry, SamplingDecision) tick time.Duration first, thereafter uint64 - hook func(Entry, SamplingDecision) } var ( diff --git a/zapcore/write_syncer.go b/zapcore/write_syncer.go index d4a1af3d0..5adcab680 100644 --- a/zapcore/write_syncer.go +++ b/zapcore/write_syncer.go @@ -47,8 +47,8 @@ func AddSync(w io.Writer) WriteSyncer { } type lockedWriteSyncer struct { - sync.Mutex ws WriteSyncer + sync.Mutex } // Lock wraps a WriteSyncer in a mutex to make it safe for concurrent use. In diff --git a/zapgrpc/zapgrpc.go b/zapgrpc/zapgrpc.go index 6823773b7..849a2d284 100644 --- a/zapgrpc/zapgrpc.go +++ b/zapgrpc/zapgrpc.go @@ -117,9 +117,9 @@ func NewLogger(l *zap.Logger, options ...Option) *Logger { // respectively. type printer struct { enab zapcore.LevelEnabler - level zapcore.Level print func(...interface{}) printf func(string, ...interface{}) + level zapcore.Level } func (v *printer) Print(args ...interface{}) { diff --git a/zapio/writer.go b/zapio/writer.go index a87d910fa..6fd175e89 100644 --- a/zapio/writer.go +++ b/zapio/writer.go @@ -54,12 +54,12 @@ type Writer struct { // The Writer will panic if Log is unspecified. Log *zap.Logger + buff bytes.Buffer + // Log level for the messages written to the provided logger. // // If unspecified, defaults to Info. Level zapcore.Level - - buff bytes.Buffer } var ( diff --git a/zaptest/observer/observer.go b/zaptest/observer/observer.go index f77f1308b..6da17d83e 100644 --- a/zaptest/observer/observer.go +++ b/zaptest/observer/observer.go @@ -35,8 +35,8 @@ import ( // ObservedLogs is a concurrency-safe, ordered collection of observed logs. type ObservedLogs struct { - mu sync.RWMutex logs []LoggedEntry + mu sync.RWMutex } // Len returns the number of items in the collection.