zaplog

package
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2021 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package zaplog provides a builder-pattern constructor for creating a logr.Logger implementation using Zap with some commonly-good defaults.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilterStacktraceOrigins

func FilterStacktraceOrigins(content []byte) []byte

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 NewZap

func NewZap() *Builder

NewZap returns a new *Builder using the default configuration.

func (*Builder) Build

func (b *Builder) Build() logr.Logger

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

func (b *Builder) Console() *Builder

Console is a shorthand for:

WithEncoder(ConsoleEncoderCreator()).
HumanFriendlyTime().
WithLevelEncoder(CapitalLevelEncoder())

A call to this function overwrites any previous value.

func (*Builder) Example

func (b *Builder) Example() *Builder

Example is a shorthand for

HumanFriendlyTime().
NoTimestamps().
NoStacktraceOnError()

A call to this function overwrites any previous value.

func (*Builder) HumanFriendlyTime

func (b *Builder) HumanFriendlyTime() *Builder

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

func (b *Builder) LogTo(w io.Writer) *Builder

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

func (b *Builder) LogUpto(logrLevel int8) *Builder

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

func (b *Builder) NoStacktraceOnError() *Builder

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

func (b *Builder) NoTimestamps() *Builder

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

func (b *Builder) Test(g *filetest.Tester) *Builder

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

func (b *Builder) WithOptions(opts ...zap.Option) *Builder

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 Encoder

type Encoder = zapcore.Encoder

Encoder is a symbolic link to zapcore.Encoder.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL