Préface
Cet article étudie principalement le SugaredLogger du zap de golang
SugaredLogger
zap@v1.16.0/sugar.go
type SugaredLogger struct { base *Logger } func (s *SugaredLogger) Named(name string) *SugaredLogger { return &SugaredLogger{base: s.base.Named(name)} } func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger { return &SugaredLogger{base: s.base.With(s.sweetenFields(args)...)} } func (s *SugaredLogger) Debug(args ...interface{}) { s.log(DebugLevel, "", args, nil) } func (s *SugaredLogger) Info(args ...interface{}) { s.log(InfoLevel, "", args, nil) } func (s *SugaredLogger) Warn(args ...interface{}) { s.log(WarnLevel, "", args, nil) } func (s *SugaredLogger) Error(args ...interface{}) { s.log(ErrorLevel, "", args, nil) } func (s *SugaredLogger) DPanic(args ...interface{}) { s.log(DPanicLevel, "", args, nil) } func (s *SugaredLogger) Panic(args ...interface{}) { s.log(PanicLevel, "", args, nil) } func (s *SugaredLogger) Fatal(args ...interface{}) { s.log(FatalLevel, "", args, nil) } func (s *SugaredLogger) Debugf(template string, args ...interface{}) { s.log(DebugLevel, template, args, nil) } func (s *SugaredLogger) Infof(template string, args ...interface{}) { s.log(InfoLevel, template, args, nil) } func (s *SugaredLogger) Warnf(template string, args ...interface{}) { s.log(WarnLevel, template, args, nil) } func (s *SugaredLogger) Errorf(template string, args ...interface{}) { s.log(ErrorLevel, template, args, nil) } func (s *SugaredLogger) DPanicf(template string, args ...interface{}) { s.log(DPanicLevel, template, args, nil) } func (s *SugaredLogger) Panicf(template string, args ...interface{}) { s.log(PanicLevel, template, args, nil) } func (s *SugaredLogger) Fatalf(template string, args ...interface{}) { s.log(FatalLevel, template, args, nil) } func (s *SugaredLogger) Debugw(msg string, keysAndValues ...interface{}) { s.log(DebugLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) Infow(msg string, keysAndValues ...interface{}) { s.log(InfoLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) Warnw(msg string, keysAndValues ...interface{}) { s.log(WarnLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) Errorw(msg string, keysAndValues ...interface{}) { s.log(ErrorLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) DPanicw(msg string, keysAndValues ...interface{}) { s.log(DPanicLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) Panicw(msg string, keysAndValues ...interface{}) { s.log(PanicLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) Fatalw(msg string, keysAndValues ...interface{}) { s.log(FatalLevel, msg, nil, keysAndValues) } func (s *SugaredLogger) Sync() error { return s.base.Sync() }
Copier après la connexion
SugaredLogger fournit des méthodes de débogage, d'informations, d'avertissement, d'erreur, de panique, dpanique et fatale (. Utilisez le format par défaut de fmt.Sprint
), et il existe également une méthode avec f qui prend en charge le format, et une méthode avec w qui prend en charge la paire clé-valeur with
使用fmt.Sprint的默认格式
),另外还有带f的支持format,带w的方法则支持with键值对level
zap@v1.16.0/level.go
const ( // DebugLevel logs are typically voluminous, and are usually disabled in // production. DebugLevel = zapcore.DebugLevel // InfoLevel is the default logging priority. InfoLevel = zapcore.InfoLevel // WarnLevel logs are more important than Info, but don't need inpidual // human review. WarnLevel = zapcore.WarnLevel // ErrorLevel logs are high-priority. If an application is running smoothly, // it shouldn't generate any error-level logs. ErrorLevel = zapcore.ErrorLevel // DPanicLevel logs are particularly important errors. In development the // logger panics after writing the message. DPanicLevel = zapcore.DPanicLevel // PanicLevel logs a message, then panics. PanicLevel = zapcore.PanicLevel // FatalLevel logs a message, then calls os.Exit(1). FatalLevel = zapcore.FatalLevel )
Copier après la connexion
zap内部的level分为debug、info、warn、error、dpanic、panic、fatal这几种
DPanic
DPanic stands for "panic in development." In development, it logs at PanicLevel; otherwise, it logs at ErrorLevel. DPanic makes it easier to catch errors that are theoretically possible, but shouldn't actually happen, without crashing in production.
DPanic in development
func dpanicInDevelopment() { logger, _ := zap.NewDevelopment() defer logger.Sync() // flushes buffer, if any sugar := logger.Sugar() sugar.DPanic("test dpanic") sugar.Info("this will not be logged") }
Copier après la connexion
DPanic在development下的效果跟panic效果类似,最后的info不会被输出
DPanic in production
func dpanicInProduction() { logger, _ := zap.NewProduction() defer logger.Sync() // flushes buffer, if any sugar := logger.Sugar() sugar.DPanic("test dpanic logged as error in not development mode") sugar.Info("this will be logged") }
Copier après la connexion
DPanic在非development下则退化为error模式,最后的info照样会输出,这样子在production下比较安全一点。
logger.check
zap@v1.16.0/logger.go
func (log *Logger) check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { // check must always be called directly by a method in the Logger interface // (e.g., Check, Info, Fatal). const callerSkipOffset = 2 // Check the level first to reduce the cost of disabled log calls. // Since Panic and higher may exit, we skip the optimization for those levels. if lvl < zapcore.DPanicLevel && !log.core.Enabled(lvl) { return nil } // Create basic checked entry thru the core; this will be non-nil if the // log message will actually be written somewhere. ent := zapcore.Entry{ LoggerName: log.name, Time: time.Now(), Level: lvl, Message: msg, } ce := log.core.Check(ent, nil) willWrite := ce != nil // Set up any required terminal behavior. switch ent.Level { case zapcore.PanicLevel: ce = ce.Should(ent, zapcore.WriteThenPanic) case zapcore.FatalLevel: onFatal := log.onFatal // Noop is the default value for CheckWriteAction, and it leads to // continued execution after a Fatal which is unexpected. if onFatal == zapcore.WriteThenNoop { onFatal = zapcore.WriteThenFatal } ce = ce.Should(ent, onFatal) case zapcore.DPanicLevel: if log.development { ce = ce.Should(ent, zapcore.WriteThenPanic) } } // Only do further annotation if we're going to write this message; checked // entries that exist only for terminal behavior don't benefit from // annotation. if !willWrite { return ce } // Thread the error output through to the CheckedEntry. ce.ErrorOutput = log.errorOutput if log.addCaller { frame, defined := getCallerFrame(log.callerSkip + callerSkipOffset) if !defined { fmt.Fprintf(log.errorOutput, "%v Logger.check error: failed to get caller\n", time.Now().UTC()) log.errorOutput.Sync() } ce.Entry.Caller = zapcore.EntryCaller{ Defined: defined, PC: frame.PC, File: frame.File, Line: frame.Line, Function: frame.Function, } } if log.addStack.Enabled(ce.Entry.Level) { ce.Entry.Stack = StackSkip("", log.callerSkip+callerSkipOffset).String } return ce }
Copier après la connexion
logger.check方法会判断lvl,如果是zapcore.DPanicLevel,则会进一步判断是否是development模式,如果是会设置ce.Should(ent, zapcore.WriteThenPanic)
小结
- zap内部的level分为debug、info、warn、error、dpanic、panic、fatal这几种
- SugaredLogger提供了debug、info、warn、error、panic、dpanic、fatal这几种方法(
使用fmt.Sprint的默认格式
level - zap@v1.16.0/level.go rrreee