当前位置 博文首页 > 使用Lumberjack+zap进行日志切割归档操作

    使用Lumberjack+zap进行日志切割归档操作

    作者:线条君 时间:2021-02-09 09:21

    使用Lumberjack+zap进行日志切割归档

    为了添加日志切割归档功能,我们将使用第三方库Lumberjack来实现。

    安装

    执行下面的命令安装Lumberjack

    go get -u github.com/natefinch/lumberjack

    zap logger中加入Lumberjack

    要在zap中加入Lumberjack支持,我们需要修改WriteSyncer代码。我们将按照下面的代码修改getLogWriter()函数:

    func getLogWriter() zapcore.WriteSyncer {
     lumberJackLogger := &lumberjack.Logger{
     Filename: "./test.log",
     MaxSize: 10,
     MaxBackups: 5,
     MaxAge:  30,
     Compress: false,
     }
     return zapcore.AddSync(&lumberJackLogger)
    }

    Lumberjack Logger采用以下属性作为输入:

    Filename: 日志文件的位置

    MaxSize:在进行切割之前,日志文件的最大大小(以MB为单位)

    MaxBackups:保留旧文件的最大个数

    MaxAges:保留旧文件的最大天数

    Compress:是否压缩/归档旧文件

    测试所有功能

    package main
    import (
     "net/http"
     "go.uber.org/zap"
     "go.uber.org/zap/zapcore"
     lumberjack "gopkg.in/natefinch/lumberjack.v2"
    )
    var sugarLogger *zap.SugaredLogger
    func main() {
     InitLogger()
     defer sugarLogger.Sync()
     for i:=0; i < 10000;i++ {
     simpleHttpGet("www.baidu.com")
     simpleHttpGet("http://www.baidu.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: "/aseit-data/gocode/src/gitlab.aseit.cn/AI_PRODUCT/psd_be_zhang/test/test.log", // ⽇志⽂件路径
     MaxSize: 1,  // 1M=1024KB=1024000byte
     MaxBackups: 5,  // 最多保留5个备份
     MaxAge:  30,  // days
     Compress: false, // 是否压缩 disabled by default
     }
     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()
     }
    }
    

    同时,可以在main函数中循环记录日志,测试日志文件是否会自动切割和归档(日志文件每1MB会切割并且在当前目录下最多保存5个备份)。

    补充:golang zap日志的使用

    zap是一个高性能日志库,github链接【传送门】,下面简单介绍一下zap的使用。

    1.下载zap包

    因为zap是uber开源的,zap内使用的包是在go.uber.org/zap,如果直接go get这个包,可能会提示get不下来。可以go get github.com/uber-go/zap,然后再把zap目录复制到src/go.uber.org下(可能还会需要go.uber.org/atomic和go.uber.org/multierr,均可参考该方法get下来)

    2.zap简单封装示例。

    package logger
     
    import (
     "go.uber.org/zap"
     "go.uber.org/zap/zapcore"
     "gopkg.in/natefinch/lumberjack.v2"
    )
     
    // error logger
    var errorLogger *zap.SugaredLogger
     
    var levelMap = map[string]zapcore.Level{
     "debug": zapcore.DebugLevel,
     "info": zapcore.InfoLevel,
     "warn": zapcore.WarnLevel,
     "error": zapcore.ErrorLevel,
     "dpanic": zapcore.DPanicLevel,
     "panic": zapcore.PanicLevel,
     "fatal": zapcore.FatalLevel,
    }
     
    func getLoggerLevel(lvl string) zapcore.Level {
     if level, ok := levelMap[lvl]; ok {
     return level
     }
     return zapcore.InfoLevel
    }
     
    func init() {
     fileName := "zap.log"
     level := getLoggerLevel("debug")
     syncWriter := zapcore.AddSync(&lumberjack.Logger{
     Filename: fileName,
     MaxSize: 1 << 30, //1G
     LocalTime: true,
     Compress: true,
     })
     encoder := zap.NewProductionEncoderConfig()
     encoder.EncodeTime = zapcore.ISO8601TimeEncoder
     core := zapcore.NewCore(zapcore.NewJSONEncoder(encoder), syncWriter, zap.NewAtomicLevelAt(level))
     logger := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
     errorLogger = logger.Sugar()
    }
     
    func Debug(args ...interface{}) {
     errorLogger.Debug(args...)
    }
     
    func Debugf(template string, args ...interface{}) {
     errorLogger.Debugf(template, args...)
    }
     
    func Info(args ...interface{}) {
     errorLogger.Info(args...)
    }
     
    func Infof(template string, args ...interface{}) {
     errorLogger.Infof(template, args...)
    }
     
    func Warn(args ...interface{}) {
     errorLogger.Warn(args...)
    }
     
    func Warnf(template string, args ...interface{}) {
     errorLogger.Warnf(template, args...)
    }
     
    func Error(args ...interface{}) {
     errorLogger.Error(args...)
    }
     
    func Errorf(template string, args ...interface{}) {
     errorLogger.Errorf(template, args...)
    }
     
    func DPanic(args ...interface{}) {
     errorLogger.DPanic(args...)
    }
     
    func DPanicf(template string, args ...interface{}) {
     errorLogger.DPanicf(template, args...)
    }
     
    func Panic(args ...interface{}) {
     errorLogger.Panic(args...)
    }
     
    func Panicf(template string, args ...interface{}) {
     errorLogger.Panicf(template, args...)
    }
     
    func Fatal(args ...interface{}) {
     errorLogger.Fatal(args...)
    }
     
    func Fatalf(template string, args ...interface{}) {
     errorLogger.Fatalf(template, args...)
    }

    3.简单封装后使用示例:

    package main
     
    import (
     "logger"
    )
     
    func main() {
     logger.Infof("simple zap logger example") 
    }

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持站长博客。如有错误或未考虑完全的地方,望不吝赐教。

    js