// Copyright (c) 2016 Uber Technologies, Inc.1//2// Permission is hereby granted, free of charge, to any person obtaining a copy3// of this software and associated documentation files (the "Software"), to deal4// in the Software without restriction, including without limitation the rights5// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell6// copies of the Software, and to permit persons to whom the Software is7// furnished to do so, subject to the following conditions:8//9// The above copyright notice and this permission notice shall be included in10// all copies or substantial portions of the Software.11//12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR13// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,14// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE15// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER16// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,17// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN18// THE SOFTWARE.1920package zap2122import (23"fmt"2425"go.uber.org/zap/zapcore"26)2728// An Option configures a Logger.29type Option interface {30apply(*Logger)31}3233// optionFunc wraps a func so it satisfies the Option interface.34type optionFunc func(*Logger)3536func (f optionFunc) apply(log *Logger) {37f(log)38}3940// WrapCore wraps or replaces the Logger's underlying zapcore.Core.41func WrapCore(f func(zapcore.Core) zapcore.Core) Option {42return optionFunc(func(log *Logger) {43log.core = f(log.core)44})45}4647// Hooks registers functions which will be called each time the Logger writes48// out an Entry. Repeated use of Hooks is additive.49//50// Hooks are useful for simple side effects, like capturing metrics for the51// number of emitted logs. More complex side effects, including anything that52// requires access to the Entry's structured fields, should be implemented as53// a zapcore.Core instead. See zapcore.RegisterHooks for details.54func Hooks(hooks ...func(zapcore.Entry) error) Option {55return optionFunc(func(log *Logger) {56log.core = zapcore.RegisterHooks(log.core, hooks...)57})58}5960// Fields adds fields to the Logger.61func Fields(fs ...Field) Option {62return optionFunc(func(log *Logger) {63log.core = log.core.With(fs)64})65}6667// ErrorOutput sets the destination for errors generated by the Logger. Note68// that this option only affects internal errors; for sample code that sends69// error-level logs to a different location from info- and debug-level logs,70// see the package-level AdvancedConfiguration example.71//72// The supplied WriteSyncer must be safe for concurrent use. The Open and73// zapcore.Lock functions are the simplest ways to protect files with a mutex.74func ErrorOutput(w zapcore.WriteSyncer) Option {75return optionFunc(func(log *Logger) {76log.errorOutput = w77})78}7980// Development puts the logger in development mode, which makes DPanic-level81// logs panic instead of simply logging an error.82func Development() Option {83return optionFunc(func(log *Logger) {84log.development = true85})86}8788// AddCaller configures the Logger to annotate each message with the filename,89// line number, and function name of zap's caller. See also WithCaller.90func AddCaller() Option {91return WithCaller(true)92}9394// WithCaller configures the Logger to annotate each message with the filename,95// line number, and function name of zap's caller, or not, depending on the96// value of enabled. This is a generalized form of AddCaller.97func WithCaller(enabled bool) Option {98return optionFunc(func(log *Logger) {99log.addCaller = enabled100})101}102103// AddCallerSkip increases the number of callers skipped by caller annotation104// (as enabled by the AddCaller option). When building wrappers around the105// Logger and SugaredLogger, supplying this Option prevents zap from always106// reporting the wrapper code as the caller.107func AddCallerSkip(skip int) Option {108return optionFunc(func(log *Logger) {109log.callerSkip += skip110})111}112113// AddStacktrace configures the Logger to record a stack trace for all messages at114// or above a given level.115func AddStacktrace(lvl zapcore.LevelEnabler) Option {116return optionFunc(func(log *Logger) {117log.addStack = lvl118})119}120121// IncreaseLevel increase the level of the logger. It has no effect if122// the passed in level tries to decrease the level of the logger.123func IncreaseLevel(lvl zapcore.LevelEnabler) Option {124return optionFunc(func(log *Logger) {125core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)126if err != nil {127fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)128} else {129log.core = core130}131})132}133134// WithPanicHook sets a CheckWriteHook to run on Panic/DPanic logs.135// Zap will call this hook after writing a log statement with a Panic/DPanic level.136//137// For example, the following builds a logger that will exit the current138// goroutine after writing a Panic/DPanic log message, but it will not start a panic.139//140// zap.New(core, zap.WithPanicHook(zapcore.WriteThenGoexit))141//142// This is useful for testing Panic/DPanic log output.143func WithPanicHook(hook zapcore.CheckWriteHook) Option {144return optionFunc(func(log *Logger) {145log.onPanic = hook146})147}148149// OnFatal sets the action to take on fatal logs.150//151// Deprecated: Use [WithFatalHook] instead.152func OnFatal(action zapcore.CheckWriteAction) Option {153return WithFatalHook(action)154}155156// WithFatalHook sets a CheckWriteHook to run on fatal logs.157// Zap will call this hook after writing a log statement with a Fatal level.158//159// For example, the following builds a logger that will exit the current160// goroutine after writing a fatal log message, but it will not exit the161// program.162//163// zap.New(core, zap.WithFatalHook(zapcore.WriteThenGoexit))164//165// It is important that the provided CheckWriteHook stops the control flow at166// the current statement to meet expectations of callers of the logger.167// We recommend calling os.Exit or runtime.Goexit inside custom hooks at168// minimum.169func WithFatalHook(hook zapcore.CheckWriteHook) Option {170return optionFunc(func(log *Logger) {171log.onFatal = hook172})173}174175// WithClock specifies the clock used by the logger to determine the current176// time for logged entries. Defaults to the system clock with time.Now.177func WithClock(clock zapcore.Clock) Option {178return optionFunc(func(log *Logger) {179log.clock = clock180})181}182183184