github.com/Laisky/zap@v1.27.0/options.go (about)

     1  // Copyright (c) 2016 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package zap
    22  
    23  import (
    24  	"fmt"
    25  
    26  	"github.com/Laisky/zap/zapcore"
    27  )
    28  
    29  // An Option configures a Logger.
    30  type Option interface {
    31  	apply(*Logger)
    32  }
    33  
    34  // optionFunc wraps a func so it satisfies the Option interface.
    35  type optionFunc func(*Logger)
    36  
    37  func (f optionFunc) apply(log *Logger) {
    38  	f(log)
    39  }
    40  
    41  // WrapCore wraps or replaces the Logger's underlying zapcore.Core.
    42  func WrapCore(f func(zapcore.Core) zapcore.Core) Option {
    43  	return optionFunc(func(log *Logger) {
    44  		log.core = f(log.core)
    45  	})
    46  }
    47  
    48  // Hooks registers functions which will be called each time the Logger writes
    49  // out an Entry. Repeated use of Hooks is additive.
    50  //
    51  // Hooks are useful for simple side effects, like capturing metrics for the
    52  // number of emitted logs. More complex side effects, including anything that
    53  // requires access to the Entry's structured fields, should be implemented as
    54  // a zapcore.Core instead. See zapcore.RegisterHooks for details.
    55  func Hooks(hooks ...func(zapcore.Entry) error) Option {
    56  	return optionFunc(func(log *Logger) {
    57  		log.core = zapcore.RegisterHooks(log.core, hooks...)
    58  	})
    59  }
    60  
    61  // HooksWithFields similiar with Hooks, but hook funcs can access fields
    62  func HooksWithFields(hooks ...func(zapcore.Entry, []zapcore.Field) error) Option {
    63  	return optionFunc(func(log *Logger) {
    64  		log.core = zapcore.RegisterHooksWithFields(log.core, hooks...)
    65  	})
    66  }
    67  
    68  // Fields adds fields to the Logger.
    69  func Fields(fs ...Field) Option {
    70  	return optionFunc(func(log *Logger) {
    71  		log.core = log.core.With(fs)
    72  	})
    73  }
    74  
    75  // ErrorOutput sets the destination for errors generated by the Logger. Note
    76  // that this option only affects internal errors; for sample code that sends
    77  // error-level logs to a different location from info- and debug-level logs,
    78  // see the package-level AdvancedConfiguration example.
    79  //
    80  // The supplied WriteSyncer must be safe for concurrent use. The Open and
    81  // zapcore.Lock functions are the simplest ways to protect files with a mutex.
    82  func ErrorOutput(w zapcore.WriteSyncer) Option {
    83  	return optionFunc(func(log *Logger) {
    84  		log.errorOutput = w
    85  	})
    86  }
    87  
    88  // Development puts the logger in development mode, which makes DPanic-level
    89  // logs panic instead of simply logging an error.
    90  func Development() Option {
    91  	return optionFunc(func(log *Logger) {
    92  		log.development = true
    93  	})
    94  }
    95  
    96  // AddCaller configures the Logger to annotate each message with the filename,
    97  // line number, and function name of zap's caller. See also WithCaller.
    98  func AddCaller() Option {
    99  	return WithCaller(true)
   100  }
   101  
   102  // WithCaller configures the Logger to annotate each message with the filename,
   103  // line number, and function name of zap's caller, or not, depending on the
   104  // value of enabled. This is a generalized form of AddCaller.
   105  func WithCaller(enabled bool) Option {
   106  	return optionFunc(func(log *Logger) {
   107  		log.addCaller = enabled
   108  	})
   109  }
   110  
   111  // AddCallerSkip increases the number of callers skipped by caller annotation
   112  // (as enabled by the AddCaller option). When building wrappers around the
   113  // Logger and SugaredLogger, supplying this Option prevents zap from always
   114  // reporting the wrapper code as the caller.
   115  func AddCallerSkip(skip int) Option {
   116  	return optionFunc(func(log *Logger) {
   117  		log.callerSkip += skip
   118  	})
   119  }
   120  
   121  // AddStacktrace configures the Logger to record a stack trace for all messages at
   122  // or above a given level.
   123  func AddStacktrace(lvl zapcore.LevelEnabler) Option {
   124  	return optionFunc(func(log *Logger) {
   125  		log.addStack = lvl
   126  	})
   127  }
   128  
   129  // IncreaseLevel increase the level of the logger. It has no effect if
   130  // the passed in level tries to decrease the level of the logger.
   131  func IncreaseLevel(lvl zapcore.LevelEnabler) Option {
   132  	return optionFunc(func(log *Logger) {
   133  		core, err := zapcore.NewIncreaseLevelCore(log.core, lvl)
   134  		if err != nil {
   135  			fmt.Fprintf(log.errorOutput, "failed to IncreaseLevel: %v\n", err)
   136  		} else {
   137  			log.core = core
   138  		}
   139  	})
   140  }
   141  
   142  // WithPanicHook sets a CheckWriteHook to run on Panic/DPanic logs.
   143  // Zap will call this hook after writing a log statement with a Panic/DPanic level.
   144  //
   145  // For example, the following builds a logger that will exit the current
   146  // goroutine after writing a Panic/DPanic log message, but it will not start a panic.
   147  //
   148  //	zap.New(core, zap.WithPanicHook(zapcore.WriteThenGoexit))
   149  //
   150  // This is useful for testing Panic/DPanic log output.
   151  func WithPanicHook(hook zapcore.CheckWriteHook) Option {
   152  	return optionFunc(func(log *Logger) {
   153  		log.onPanic = hook
   154  	})
   155  }
   156  
   157  // OnFatal sets the action to take on fatal logs.
   158  //
   159  // Deprecated: Use [WithFatalHook] instead.
   160  func OnFatal(action zapcore.CheckWriteAction) Option {
   161  	return WithFatalHook(action)
   162  }
   163  
   164  // WithFatalHook sets a CheckWriteHook to run on fatal logs.
   165  // Zap will call this hook after writing a log statement with a Fatal level.
   166  //
   167  // For example, the following builds a logger that will exit the current
   168  // goroutine after writing a fatal log message, but it will not exit the
   169  // program.
   170  //
   171  //	zap.New(core, zap.WithFatalHook(zapcore.WriteThenGoexit))
   172  //
   173  // It is important that the provided CheckWriteHook stops the control flow at
   174  // the current statement to meet expectations of callers of the logger.
   175  // We recommend calling os.Exit or runtime.Goexit inside custom hooks at
   176  // minimum.
   177  func WithFatalHook(hook zapcore.CheckWriteHook) Option {
   178  	return optionFunc(func(log *Logger) {
   179  		log.onFatal = hook
   180  	})
   181  }
   182  
   183  // WithClock specifies the clock used by the logger to determine the current
   184  // time for logged entries. Defaults to the system clock with time.Now.
   185  func WithClock(clock zapcore.Clock) Option {
   186  	return optionFunc(func(log *Logger) {
   187  		log.clock = clock
   188  	})
   189  }