Documentation ¶
Overview ¶
Package zaplog provides a builder-pattern constructor for creating a logr.Logger implementation using Zap with some commonly-good defaults.
Index ¶
- func FilterStacktraceOrigins(content []byte) []byte
- type Builder
- func (b *Builder) Build() logr.Logger
- func (b *Builder) Console() *Builder
- func (b *Builder) Example() *Builder
- func (b *Builder) HumanFriendlyTime() *Builder
- func (b *Builder) LogTo(w io.Writer) *Builder
- func (b *Builder) LogUpto(logrLevel int8) *Builder
- func (b *Builder) NoStacktraceOnError() *Builder
- func (b *Builder) NoTimestamps() *Builder
- func (b *Builder) Test(g *filetest.Tester) *Builder
- func (b *Builder) WithEncoderConfig(cfg EncoderConfig) *Builder
- func (b *Builder) WithEncoderConfigOption(opts ...EncoderConfigOption) *Builder
- func (b *Builder) WithEncoderCreator(encoderCreator EncoderCreator) *Builder
- func (b *Builder) WithLevelEncoder(levelEnc LevelEncoder) *Builder
- func (b *Builder) WithOptions(opts ...zap.Option) *Builder
- type Encoder
- type EncoderConfig
- type EncoderConfigOption
- type EncoderCreator
- type LevelEncoder
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FilterStacktraceOrigins ¶
FilterStacktraceOrigins removes every line in content that starts with tab. It is meant to be used for filtering call stack output from for example a logger when testing (as the exact lines of caller origin might vary for instance across Go versions).
TODO: Make this work with JSON output as well.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder is a builder-pattern struct for building a logr.Logger using go.uber.org/zap.
The default configuration uses the production encoder configuration, writes JSON, includes the V log levels in the level name, and logs to os.Stdout.
Example (Calldepth) ¶
// Build an example logger called bar that logs levels <= 1. var buf bytes.Buffer log := NewZap(). NoTimestamps(). LogTo(&buf). Console(). LogUpto(1). Build(). WithName("bar") // Sample info usage log.Info("some message", "foo", true) // This is literally meant to cause a DPANIC; one must not give zap // fields to a logr.Logger. Provoke a call stack here in the output. log.WithValues("bar", 1).V(1).Info("hello", zap.Float32("foo", 23.2)) // Sample error usage. See the call stack in action. err := errors.New("unexpected error") //nolint:goerr113 log.Error(err, "I don't know what happened here", "duration", time.Minute) // Verify that v=2 is disabled (i.e. discarded), but v=1 is enabled log.V(1).Info("am I enabled?", "enabled", log.V(1).Enabled()) log.V(2).Info("am I enabled?", "enabled", log.V(2).Enabled()) // Filter the call stack before outputting fmt.Println(string(FilterStacktraceOrigins(buf.Bytes())))
Output: INFO(v=0) bar some message {"foo": true} DPANIC bar strongly-typed Zap Field passed to logr {"bar": 1, "zap field": {"Key":"foo","Type":10,"Integer":1102682522,"String":"","Interface":null}} github.com/go-logr/zapr.(*zapLogger).Info github.com/luxas/deklarative/tracing/zaplog.ExampleBuilder_calldepth testing.runExample testing.runExamples testing.(*M).Run main.main runtime.main DEBUG(v=1) bar hello {"bar": 1} ERROR bar I don't know what happened here {"duration": "1m0s", "error": "unexpected error"} github.com/luxas/deklarative/tracing/zaplog.ExampleBuilder_calldepth testing.runExample testing.runExamples testing.(*M).Run main.main runtime.main DEBUG(v=1) bar am I enabled? {"enabled": true}
Example (Console) ¶
// Build an example logger called bar that logs levels <= 1. log := NewZap().Example().Console().LogUpto(1).Build().WithName("bar") // Sample info usage log.Info("some message", "foo", true) log.WithValues("bar", 1).V(1).Info("hello") // Sample error usage err := errors.New("unexpected error") //nolint:goerr113 log.Error(err, "I don't know what happened here", "duration", time.Minute) // Verify that v=2 is disabled (i.e. discarded), but v=1 is enabled log.V(1).Info("am I enabled?", "enabled", log.V(1).Enabled()) log.V(2).Info("am I enabled?", "enabled", log.V(2).Enabled())
Output: INFO(v=0) bar some message {"foo": true} DEBUG(v=1) bar hello {"bar": 1} ERROR bar I don't know what happened here {"duration": "1m0s", "error": "unexpected error"} DEBUG(v=1) bar am I enabled? {"enabled": true}
Example (Custom) ¶
// Build an example logger called bar that logs levels <= 1. var buf bytes.Buffer log := NewZap(). Example(). LogUpto(1). WithEncoderConfig(DevelopmentEncoderConfig()). LogTo(&buf). Build(). WithName("bar") // Sample info usage log.Info("some message", "foo", true) log.WithValues("bar", 1).V(1).Info("hello") // Sample error usage err := errors.New("unexpected error") //nolint:goerr113 log.Error(err, "I don't know what happened here", "duration", time.Minute) // Verify that v=2 is disabled (i.e. discarded), but v=1 is enabled log.V(1).Info("am I enabled?", "enabled", log.V(1).Enabled()) log.V(2).Info("am I enabled?", "enabled", log.V(2).Enabled()) fmt.Println(buf.String())
Output: {"L":"info(v=0)","N":"bar","M":"some message","foo":true} {"L":"debug(v=1)","N":"bar","M":"hello","bar":1} {"L":"error","N":"bar","M":"I don't know what happened here","duration":"1m0s","error":"unexpected error"} {"L":"debug(v=1)","N":"bar","M":"am I enabled?","enabled":true}
Example (Json) ¶
// Build an example logger called bar that logs levels <= 1. log := NewZap().Example().LogUpto(1).Build().WithName("bar") // Sample info usage log.Info("some message", "foo", true) log.WithValues("bar", 1).V(1).Info("hello") // Sample error usage err := errors.New("unexpected error") //nolint:goerr113 log.Error(err, "I don't know what happened here", "duration", time.Minute) // Verify that v=2 is disabled (i.e. discarded), but v=1 is enabled log.V(1).Info("am I enabled?", "enabled", log.V(1).Enabled()) log.V(2).Info("am I enabled?", "enabled", log.V(2).Enabled())
Output: {"level":"info(v=0)","logger":"bar","msg":"some message","foo":true} {"level":"debug(v=1)","logger":"bar","msg":"hello","bar":1} {"level":"error","logger":"bar","msg":"I don't know what happened here","duration":"1m0s","error":"unexpected error"} {"level":"debug(v=1)","logger":"bar","msg":"am I enabled?","enabled":true}
func (*Builder) Build ¶
Build builds the logger with the configured options.
By default the logger name is an empty string, and the log level is 0.
func (*Builder) Console ¶
Console is a shorthand for:
WithEncoder(ConsoleEncoderCreator()). HumanFriendlyTime(). WithLevelEncoder(CapitalLevelEncoder())
A call to this function overwrites any previous value.
func (*Builder) Example ¶
Example is a shorthand for
HumanFriendlyTime(). NoTimestamps(). NoStacktraceOnError()
A call to this function overwrites any previous value.
func (*Builder) HumanFriendlyTime ¶
HumanFriendlyTime serializes time.Time and time.Duration in a human-friendly manner.
It serializes a time.Time to an ISO8601-formatted string with millisecond precision. It serializes a time.Duration using its built-in String method.
It corresponds to setting EncoderConfig fields as follows:
.EncodeTime = zapcore.ISO8601TimeEncoder .EncodeDuration = zapcore.StringDurationEncoder
A call to this function overwrites any previous value.
func (*Builder) LogTo ¶
LogTo specifies where to write logs. If you want to write to multiple destinations, use io.MultiWriter or preferably, zapcore.NewMultiWriteSyncer.
A zapcore.WriteSyncer shall be passed in if possible, otherwise a no-op Sync method will be used internally. The resulting WriteSyncer is automatically locked using zapcore.Lock, so it can be used in a thread-safe manner.
Defaults to os.Stdout.
A call to this function overwrites any previous value.
func (*Builder) LogUpto ¶
LogUpto specifies the logr level that shall be used. All log messages from a logr.Logger with a log level _less than or equal to_ logrLevel will be output.
To convert between zap and logr log levels, multiply by -1 like follows:
Level Zap Logr -N N Debug -1 1 Info 0 0 (default) Warn 1 N/A Error 2 N/A
The default level of 0 means that logr.Info and logr.Error calls will be output, unless logr.Logger.V() is used to raise the level.
According to logr.Logger, "it's illegal to pass a log level less than zero.", hence, negative logrLevel values are disallowed.
A call to this function overwrites any previous value.
func (*Builder) NoStacktraceOnError ¶
NoStacktraceOnError makes the logger not output a stack trace when an error is logged. This is done by moving the stack trace level to only be output for the DPanicLevel or higher (zap) levels.
A call to this function overwrites any previous value.
func (*Builder) NoTimestamps ¶
NoTimestamps omits timestamps in the logs. It's useful for deterministic output in examples and tests.
It corresponds to setting EncoderConfig.TimeKey = zapcore.OmitKey.
By default timestamps are included in the log output.
A call to this function overwrites any previous value.
func (*Builder) Test ¶
Test is a shorthand for verifying log output in a test with the help of the filetest package. Given a filetest.Tester, this will make the logger log to a file under testdata/ with the name of the test + the ".log" suffix.
FilterStacktraceOrigins is applied before verifying the output such that in console mode the stack trace is filtered.
func (*Builder) WithEncoderConfig ¶
func (b *Builder) WithEncoderConfig(cfg EncoderConfig) *Builder
WithEncoderConfig lets the user fine-tune how to encode/format logs.
Defaults to zap.NewProductionEncoderConfig().
A call to this function overwrites any previous value.
func (*Builder) WithEncoderConfigOption ¶
func (b *Builder) WithEncoderConfigOption(opts ...EncoderConfigOption) *Builder
WithEncoderConfigOption registers a function that mutates the registered EncoderConfig from WithEncoderConfig at Build() time. This is useful for "patching" an individual part of the EncoderConfig, instead of overwriting everything.
A call to this function appends to the list of previous values.
func (*Builder) WithEncoderCreator ¶
func (b *Builder) WithEncoderCreator(encoderCreator EncoderCreator) *Builder
WithEncoderCreator uses a specific EncoderCreator to create the encoder.
Defaults to JSONEncoderCreator().
A call to this function overwrites any previous value.
func (*Builder) WithLevelEncoder ¶
func (b *Builder) WithLevelEncoder(levelEnc LevelEncoder) *Builder
WithLevelEncoder customizes how the log level is encoded.
The default is LowercaseLevelEncoder.
A call to this function overwrites any previous value.
func (*Builder) WithOptions ¶
WithOptions appends options for configuring zap.
Options by default applied in Build() are:
zap.AddStacktrace(zap.ErrorLevel) zap.ErrorOutput(sink)
It is possible to overwrite these default using this method.
A call to this function appends to the list of previous values.
type EncoderConfig ¶
type EncoderConfig = zapcore.EncoderConfig
EncoderConfig is a symbolic link to zapcore.EncoderConfig.
func DevelopmentEncoderConfig ¶
func DevelopmentEncoderConfig() EncoderConfig
DevelopmentEncoderConfig is a symbolic link to zap.NewDevelopmentEncoderConfig().
func ProductionEncoderConfig ¶
func ProductionEncoderConfig() EncoderConfig
ProductionEncoderConfig is a symbolic link to zap.NewProductionEncoderConfig().
type EncoderConfigOption ¶
type EncoderConfigOption func(*EncoderConfig)
EncoderConfigOption represents a function that applies an option to the EncoderConfig.
type EncoderCreator ¶
type EncoderCreator func(EncoderConfig) Encoder
EncoderCreator represents an Encoder constructor given a populated EncoderConfig.
func ConsoleEncoderCreator ¶
func ConsoleEncoderCreator() EncoderCreator
ConsoleEncoderCreator is a symbolic link to zapcore.NewConsoleEncoder.
func JSONEncoderCreator ¶
func JSONEncoderCreator() EncoderCreator
JSONEncoderCreator is a symbolic link to zapcore.NewJSONEncoder.
type LevelEncoder ¶
type LevelEncoder = zapcore.LevelEncoder
LevelEncoder is a symbolic link to zapcore.LevelEncoder.
func CapitalLevelEncoder ¶
func CapitalLevelEncoder() LevelEncoder
CapitalLevelEncoder extends the zapcore.CapitalLevelEncoder by adding a "(v={V})" to all levels where {V} is the logr level.
func LowercaseLevelEncoder ¶
func LowercaseLevelEncoder() LevelEncoder
LowercaseLevelEncoder is the default LevelEncoder; it extends the zapcore.LowercaseLevelEncoder by adding a "(v={V})" to all levels where {V} is the logr level.
TODO: Once we can upgrade to logr v1.x, and https://github.com/go-logr/zapr/pull/37 has landed, we can make log levels more easily a field.