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 }