环境:Go1.18.2 windows/amd64 zap:go.uber.org/zap v1.7.0
近期,在做项目案例的时候,发现使用zap作为日志时,相同的日志内容重复输出,这些天,深入分析了一下zap的源码,发现了该问题出现的原因,现在总结一下。
首先,问题重现:
例如:程序启动时的日志每一条Info级别的日志都是重复打印了两遍
解决之后:
解决过程
- zap 支持设置日志级别,只有日志语句的级别(如:log.Info)大于等于设置配置文件时zapcore的日志级别,给定语句才能够被记录下来。
- zap 支持多个core记录日志,能够把日志写到不同的位置,比如文件或者控制台。
- 如果设置每一个core都能够把日志输出到控制台,若有某一个日志打印语句,存在多个比它日志级别低的core,那么那些core都打印这一条日志内容,都是一样的,这就给我造成了重复打印日志的结果
修改前代码:(部分)
func Zap() (logger *zap.Logger) {
cores := make([]zapcore.Core, 0, 7)
// 创建七个日志core 分别具有不同的日志级别
debugLevel := getEncoderCore(zap.DebugLevel)
infoLevel := getEncoderCore(zap.InfoLevel)
warnLevel := getEncoderCore(zap.WarnLevel)
errorLevel := getEncoderCore(zap.ErrorLevel)
dPanicLevel := getEncoderCore(zap.DPanicLevel)
panicLevel := getEncoderCore(zap.PanicLevel)
fatalLevel := getEncoderCore(zap.FatalLevel)
switch global.GVA_CONFIG.Zap.Level { // debug 级别
case "debug", "DEBUG":
cores = append(cores, debugLevel, infoLevel, warnLevel, errorLevel
}
// 通过多个日志core创建日志变量
logger = zap.New(zapcore.NewTee(cores...), zap.AddCaller())
return logger
}
- 创建七个日志core 分别具有不同的日志级别
- 设置每一个日志core都能够打印到控制台
- 创建logger
更改之后的代码:
- 每一个级别日志core 固定输出到文件,再建立一个core专门输出到控制台。
cores := make([]zapcore.Core, 0, 8)
debugLevel := getEncoderCore(zap.DebugLevel)
infoLevel := getEncoderCore(zap.InfoLevel)
warnLevel := getEncoderCore(zap.WarnLevel)
errorLevel := getEncoderCore(zap.ErrorLevel)
dPanicLevel := getEncoderCore(zap.DPanicLevel)
panicLevel := getEncoderCore(zap.PanicLevel)
fatalLevel := getEncoderCore(zap.FatalLevel)
switch global.GVA_CONFIG.Zap.Level {
case "debug", "DEBUG":
if global.GVA_CONFIG.Zap.LogInConsole { // true
cores = append(cores, zapcore.NewCore(getEncoder(), os.Stdout, zap.DebugLevel))
}
cores = append(cores, debugLevel, infoLevel, warnLevel, errorLevel, dPanicLevel, panicLevel, fatalLevel)
}