• 日志库Zap


    1、介绍

    Zap提供了两种类型的日志记录器—Sugared LoggerLogger

    在性能很好但不是很关键的上下文中,使用SugaredLogger。它比其他结构化日志记录包快4-10倍,并且支持结构化和printf风格的日志记录。

    在每一微秒和每一次内存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,内存分配次数也更少,但它只支持强类型的结构化日志记录。

    2、logger的使用-使用默认方法

    通过调用zap.NewProduction()/zap.NewDevelopment()或者zap.Example()创建一个Logger。它们的区别在于记录的信息不同。production logger默认记录调用函数信息、日期和时间等。

    var logger *zap.Logger
    
    func main() {
    	InitLogger()
      defer logger.Sync()
    	simpleHttpGet("www.google.com")
    	simpleHttpGet("http://www.google.com")
    }
    
    func InitLogger() {
    	logger, _ = zap.NewProduction()
    }
    
    func simpleHttpGet(url string) {
    	resp, err := http.Get(url)
    	if err != nil {
    		logger.Error(
    			"Error fetching url..",
    			zap.String("url", url),
    			zap.Error(err))
    	} else {
    		logger.Info("Success..",
    			zap.String("statusCode", resp.Status),
    			zap.String("url", url))
    		resp.Body.Close()
    	}
    }
    

      

    3、Sugared Logger的使用-使用默认方法

    与logger的区别是,SugaredLoggerprintf格式记录语句。

    var sugarLogger *zap.SugaredLogger
    
    func main() {
    	InitLogger()
    	defer sugarLogger.Sync()
    	simpleHttpGet("www.google.com")
    	simpleHttpGet("http://www.google.com")
    }
    
    func InitLogger() {
      logger, _ := zap.NewProduction()
    	sugarLogger = logger.Sugar()
    }
    
    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()
    	}
    }
    

      

    4、自定义logger的输出

     1)将日志写入文件而不是终端

    只需要修改上面代码的InitLogger()函数:

    func InitLogger() {
    	writeSyncer := getLogWriter()
    	encoder := getEncoder()
    	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
    
    	logger := zap.New(core)
    	sugarLogger = logger.Sugar()
    }
    
    func getEncoder() zapcore.Encoder {
    	return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
    }
    
    func getLogWriter() zapcore.WriteSyncer {
    	file, _ := os.Create("./test.log")
    	return zapcore.AddSync(file)
    }
    

     2)将JSON Encoder更改为普通的Log Encoder

    NewJSONEncoder()更改为NewConsoleEncoder()

     3)更改时间编码并添加调用者详细信息

    修改时间编码器:

    func getEncoder() zapcore.Encoder {
    	encoderConfig := zap.NewProductionEncoderConfig()
    	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
    	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
    	return zapcore.NewConsoleEncoder(encoderConfig)
    }
    

     4)添加将调用函数信息记录到日志中的功能,在zap.New(..)函数中添加一个Option

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

     5)AddCallerSkip:

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

     6)将日志输出到多个位置:

    func getLogWriter() zapcore.WriteSyncer {
    	file, _ := os.Create("./test.log")
    	// 利用io.MultiWriter支持文件和终端两个输出目标
    	ws := io.MultiWriter(file, os.Stdout)
    	return zapcore.AddSync(ws)
    }
    

     7)将err日志单独输出到文件:

    func InitLogger() {
    	encoder := getEncoder()
    	// test.log记录全量日志
    	logF, _ := os.Create("./test.log")
    	c1 := zapcore.NewCore(encoder, zapcore.AddSync(logF), zapcore.DebugLevel)
    	// test.err.log记录ERROR级别的日志
    	errF, _ := os.Create("./test.err.log")
    	c2 := zapcore.NewCore(encoder, zapcore.AddSync(errF), zap.ErrorLevel)
    	// 使用NewTee将c1和c2合并到core
    	core := zapcore.NewTee(c1, c2)
    	logger = zap.New(core, zap.AddCaller())
    }
    

      

    完整代码:

    package main
    
    import (
    	"go.uber.org/zap/zapcore"
    	"io"
    	"net/http"
    	"os"
    )
    
    import (
    	"go.uber.org/zap"
    )
    
    var sugarLogger *zap.SugaredLogger
    
    func main() {
    	InitLogger()
    	defer sugarLogger.Sync()
    	simpleHttpGet("www.google.com")
    	simpleHttpGet("http://www.google.com")
    }
    
    func InitLogger() {
    	writeSyncer := getLogWriter()
    	encoder := getEncoder()
    	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
    
    	logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
    	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 {
    	file, _ := os.Create("./test.log")
    	// 利用io.MultiWriter支持文件和终端两个输出目标
    	ws := io.MultiWriter(file, os.Stdout)
    	return zapcore.AddSync(ws)
    }
    
    func simpleHttpGet(url string) {
    	resp, err := http.Get(url)
    	if err != nil {
    		sugarLogger.Error(
    			"Error fetching url..",
    			zap.String("url", url),
    			zap.Error(err))
    	} else {
    		sugarLogger.Info("Success..",
    			zap.String("statusCode", resp.Status),
    			zap.String("url", url))
    		resp.Body.Close()
    	}
    }
    

      

    参考:在Go语言项目中使用Zap日志库 | 李文周的博客 (liwenzhou.com)

  • 相关阅读:
    3-4: 一元多项式的乘法与加法运算
    设计模式一装饰者模式
    设计模式一组合模式
    设计模式一命令模式
    设计模式一建造者模式
    设计模式一桥接模式
    设计模式一适配器模式
    设计模式一抽象工厂模式
    排序算法一二分排序
    排序算法一希尔排序
  • 原文地址:https://www.cnblogs.com/mango1997/p/16598294.html
Copyright © 2020-2023  润新知