Go使用zap+ratatelogs实现日志文件输出与分割

需求:将日志文件统一输出到D:/bian/logs/dspcollect.log文件中,go程序重启后日志累加写入文件,每24小时分割一次日志,保存30天内的日志文件。

对比了几款go 日志框架:zap , logrus ,seelog等。其中logrus是目前Github上star数量最多的日志库,能强大,性能高效,而且具有高度灵活性,提供了自定义插件的功能。zap是Uber推出的一个快速、结构化的分级日志库.具有强大的ad-hoc分析功能,并且具有灵活的仪表盘。seelog提供了灵活的异步调度、格式化和过滤功能。

关于logrus的使用可以参考这篇博客:https://mojotv.cn/2018/12/27/golang-logrus-tutorial

本文主要使用zap,涉及到的go包如下:

github.com/lestrrat/go-file-rotatelogs  //由于zap,logrus都不支持日志分割,所有依赖rotate进行日志分割

go.uber.org/zap

package main

import (
	"github.com/lestrrat/go-file-rotatelogs"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"io"
	"time"
)

var Logger *zap.SugaredLogger

func main() {
	Logger.Error("error....")
	Logger.Info("info....")
	Logger.Warn("warn....")

}

func init() {
	initLogger()
}

func initLogger() {
    logPath := "D:/bian/logs/dspcollect.log"
	if !Exists(logPath) {
		file, err := os.Create(logPath)
		defer file.Close()
		if err != nil{
			fmt.Println("mkdir logPath err!")
			return
		}
	}
	encoder := initEncoder()

	// 想要将日常文件区分开来,可以实现多个日志等级接口
	/*infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl < zapcore.WarnLevel
	})*/
	debugLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl >= zapcore.DebugLevel
	})

	// 获取 info、warn日志文件的io.Writer
	//infoIoWriter := getWriter("D:/bian/logs/dspcollect.log")
	warnIoWriter := getWriter("D:/bian/logs/dspcollect.log")

	// 创建Logger
	core := zapcore.NewTee(
		//zapcore.NewCore(encoder, zapcore.AddSync(infoIoWriter), infoLevel),
		zapcore.NewCore(encoder, zapcore.AddSync(warnIoWriter), debugLevel),
	)
	logger := zap.New(core, zap.AddCaller()) // 需要传入 zap.AddCaller() 才会显示打日志点的文件名和行数
	Logger = logger.Sugar()
}

//初始化Encoder
func initEncoder() zapcore.Encoder {
	return zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
		MessageKey:  "msg",
		LevelKey:    "level",
		TimeKey:     "time",
		CallerKey:   "file",
		EncodeLevel: zapcore.CapitalLevelEncoder, //基本zapcore.LowercaseLevelEncoder。将日志级别字符串转化为小写
		EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
			enc.AppendString(t.Format("2006-01-02 15:04:05"))
		},
		EncodeCaller: zapcore.ShortCallerEncoder, //一般zapcore.ShortCallerEncoder,以包/文件:行号 格式化调用堆栈
		EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) { //一般zapcore.SecondsDurationEncoder,执行消耗的时间转化成浮点型的秒
			enc.AppendInt64(int64(d) / 1000000)
		},
	})
}

//日志文件切割
func getWriter(filename string) io.Writer {
	// 保存30天内的日志,每24小时(整点)分割一次日志
	hook, err := rotatelogs.New(
		filename+".%Y%m%d",
		rotatelogs.WithLinkName(filename),
		rotatelogs.WithMaxAge(time.Hour*24*30),
		rotatelogs.WithRotationTime(time.Hour*24),
	)

	if err != nil {
		panic(err)
	}
	return hook
}

//查看文件/文件夹是否存在
func Exists(path string) bool {
	_, err := os.Stat(path)
	if err != nil{
		if os.IsExist(err){
			return true
		}
		return false
	}
	return true
}

日志效果:

Go使用zap+ratatelogs实现日志文件输出与分割_第1张图片

分割效果:

 

你可能感兴趣的:(Golang基础)