• 技术文章 >后端开发 >Golang

    带你研究一下go zap的SugaredLogger!

    藏色散人藏色散人2021-09-13 15:41:24转载76

    本文主要研究一下golang的zap的SugaredLogger

    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()
    }
    SugaredLogger提供了debug、info、warn、error、panic、dpanic、fatal这几种方法(使用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
    )
    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")
    }
    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")
    }
    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
    }
    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的默认格式),另外还有带f的支持format,带w的方法则支持with键值对
    • DPanic在development下的效果跟panic效果类似,在非development下则退化为error模式

    以上就是带你研究一下go zap的SugaredLogger!的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:segmentfault,如有侵犯,请联系admin@php.cn删除
    专题推荐:golang
    上一篇:分步骤解析GO项目test的写法 下一篇:分析Golang的WaitGroup陷阱并解决问题
    线上培训班

    相关文章推荐

    • go语言如何初始化结构体的成员变量• go语言空结构体的用法是什么• go语言有哪些包• go语言中的rune怎么获取字符长度• go语言字符串怎么求指定子串

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网