• zap日志库


    一、默认版log库

    1.配置日志输出文件

    func SetupLogger() {
        logFileLocation, _ := os.OpenFile("/Users/q1mi/test.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0744)
        log.SetOutput(logFileLocation)
    }
    

    2.使用logger

    func simpleHttpGet(url string) {
        resp, err := http.Get(url)
        if err != nil {
            log.Printf("Error fetching url %s : %s", url, err.Error())
        } else {
            log.Printf("Status Code for %s : %s", url, resp.Status)
            resp.Body.Close()
        }
    }
    
    1. 三个打印函数Print 、Panic 、Fatal
    • 对每一类接口其提供了3中调用方式,分别是 "Xxxx 、 Xxxxln 、Xxxxf",基本和fmt中的相关函数类似
    • log.Fatal 接口,打印输出后,接着调用系统的 os.exit(1) 接口
    • log.Panic接口,该函数把日志内容刷到标准错误后,调用 panic 函数

    log包存在的劣势

    • 仅限基本的日志级别
    • 但是它缺少一个ERROR日志级别,这个级别可以在不抛出panic或退出程序的情况下记录错误
    • 但是它缺少一个ERROR日志级别,这个级别可以在不抛出panic或退出程序的情况下记录错误
    • 不提供日志切割的能力,如日志文件大小,存储管理

    二、go.uber.org/zap 又快又好用的日志包

    安装 go get -u go.uber.org/zap

    1)配置Zap Logger

    Zap提供了两种类型的日志记录器 SugaredLoggerLogger
    相对来说,SugaredLogger比 Logger封装更高级,支持结构化和printf风格,
    但是Logger,适用于每一微秒和每一次内存分配都很重要的上下文中,因为只支持强类型的结构化日志记录,比SugaredLogger更快,内存分配次数也更少,

    2)简单调用

    • zap.NewProduction()、zap.NewDevelopment()、zap.Example()创建一个Logger
    • 上面每一个函数都将创建一个logger。唯一的区别在于它将记录的信息不同。例如production logger默认记录调用函数信息、日期和时间等
    • Logger调用Info/Error等,默认日志打印到console
    var logger *zap.Logger
    
    func main() {
        InitLogger()
        defer logger.Sync()  //zap底层设置了缓存,sync将缓存同步到文件中
        simpleHttpGet("www.google.com")
        simpleHttpGet("http://www.google.com")
    }
    
    func InitLogger() {
        logger, _ = zap.NewProduction()
        sugarLogger = logger.Sugar()   //升级为sugar
    }
    
    func simpleHttpGet(url string) {
        resp, err := http.Get(url)
        if err != nil {
            logger.Error(
                "Error fetching url..",
                zap.String("url", url),  // 输出 url: XXXX,
                zap.Error(err))
        } else {
            logger.Info("Success..",
                zap.String("statusCode", resp.Status),  //zap.type() 强类型,写入日志,zap.StringP,输出记录指针,zap.StringL 输出记录字符串数组
                zap.String("url", url))
            resp.Body.Close()
        }
    }
    

    输出结果 默认有caller

    {"level":"error","ts":1572159149.923002,"caller":"logic/temp2.go:27","msg":"Error fetching URL www.sogo.com : Error = Get www.sogo.com: unsupported protocol scheme ""","stacktrace":"main.simpleHttpGet
    	/Users/q1mi/zap_demo/logic/temp2.go:27
    main.main
    	/Users/q1mi/zap_demo/logic/temp2.go:14
    runtime.main
    	/usr/local/go/src/runtime/proc.go:203"}
    {"level":"info","ts":1572159150.192585,"caller":"logic/temp2.go:29","msg":"Success! statusCode = 200 OK for URL http://www.sogo.com"}
    

    3)定制化调用

    func New(core zapcore.Core, options ...Option) *Logger
    其中zapcore.Core需要三个配置——Encoder,WriteSyncer,LogLevel

    • Encoder 编码器(如何写入日志),使用json编码NewsJSONEncoder(),再使用预先设置的ProductionEncoderConfig()。
      zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())

    • WriterSyncer :指定日志将写到哪里去。我们使用zapcore.AddSync()函数并且将打开的文件句柄传进去

    file, _ := os.Create("./test.log") 
    writeSyncer := zapcore.AddSync(file)
    
    • Log Level:哪种级别的日志将被写入
    func InitLogger() {
        file, _ := os.Create("./test.log") 
    
        writeSyncer := zapcore.AddSync(file)
        encoder := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()) //json输出格式
        core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
    
        logger := zap.New(core)
        sugarLogger = logger.Sugar()
    }
    

    输出结果,无caller,需额外配置

    {"level":"debug","ts":1572160754.994731,"msg":"Trying to hit GET request for www.sogo.com"}
    {"level":"error","ts":1572160754.994982,"msg":"Error fetching URL www.sogo.com : Error = Get www.sogo.com: unsupported protocol scheme """}
    {"level":"debug","ts":1572160754.994996,"msg":"Trying to hit GET request for http://www.sogo.com"}
    {"level":"info","ts":1572160757.3755069,"msg":"Success! statusCode = 200 OK for URL http://www.sogo.com"}
    

    添加调用详细信息,即那行代码出错

    logger := zap.New(core, zap.AddCaller())

    修改时间格式

    大写记录日志级别

    通过修改core

        encoderConfig := zap.NewProductionEncoderConfig()
        encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
        encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
        encoder := zapcore.NewConsoleEncoder(encoderConfig)
    
    019-10-27T15:33:29.855+0800    DEBUG   logic/temp2.go:47   Trying to hit GET request for www.sogo.com
    2019-10-27T15:33:29.855+0800    ERROR   logic/temp2.go:50   Error fetching URL www.sogo.com : Error = Get www.sogo.com: unsupported protocol scheme ""
    2019-10-27T15:33:29.856+0800    DEBUG   logic/temp2.go:47   Trying to hit GET request for http://www.sogo.com
    2019-10-27T15:33:30.125+0800    INFO    logic/temp2.go:52   Success! statusCode = 200 OK for URL http://www.sogo.com
    

    三、使用Lumberjack进行日志切割归档

    go get -u github.com/natefinch/lumberjack

    • 使用lumberjack 修改WriterSyncer
    lumberJackLogger := &lumberjack.Logger{
            Filename:   "./test.log",
            MaxSize:    10,  //日志文件最大存储大小(MB)
            MaxBackups: 5, //保留旧文件最大个数
            MaxAge:     30, //保留旧文件最大天数
            Compress:   false, //是否压缩
        }
    WriterSyncer := zapcore.AddSync(lumberJackLogger)
    

    最终完整zap/lumberjack代码示例如下:

    package main
    
    import (
        "net/http"
    
        "github.com/natefinch/lumberjack"
        "go.uber.org/zap"
        "go.uber.org/zap/zapcore"
    )
    
    var sugarLogger *zap.SugaredLogger
    
    func main() {
        InitLogger()
        defer sugarLogger.Sync()
        simpleHttpGet("www.sogo.com")
        simpleHttpGet("http://www.sogo.com")
    }
    
    func InitLogger() {
        writeSyncer := getLogWriter()
        encoder := getEncoder()
        core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
    
        logger := zap.New(core, zap.AddCaller())
        sugarLogger = logger.Sugar()
    }
    
    func getEncoder() zapcore.Encoder {
        encoderConfig := zap.NewProductionEncoderConfig()
        encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
        encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
        return zapcore.NewConsoleEncoder(encoderConfig)
    }
    
    func getLogWriter() zapcore.WriteSyncer {
        lumberJackLogger := &lumberjack.Logger{
            Filename:   "./test.log",
            MaxSize:    1,
            MaxBackups: 5,
            MaxAge:     30,
            Compress:   false,
        }
        return zapcore.AddSync(lumberJackLogger)
    }
    
    func simpleHttpGet(url string) {
        sugarLogger.Debugf("Trying to hit GET request for %s", url)
        resp, err := http.Get(url)
        if err != nil {
            sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
        } else {
            sugarLogger.Infof("Success! statusCode = %s for URL %s", resp.Status, url)
            resp.Body.Close()
        }
    }
    
  • 相关阅读:
    [ES6] 15. Generators -- 2
    [ES6] 14. Generator -- 1. yield & next()
    [ES6] 13. Using the ES6 spread operator ...
    [ES6] 12. Shorthand Properties in ES6
    [ES6] 11. String Templates
    计算机-DB:OLAP(联机分析处理)
    计算机-事务:OLTP(联机事务处理过程)
    软件-数据库-分布式:HBase
    架构-分布式:Hadoop
    计算机-数据仓库:DW/DWH
  • 原文地址:https://www.cnblogs.com/fanzou/p/13540382.html
Copyright © 2020-2023  润新知