深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)
日志处理经常有以下几个需求:
1、不同级别的日志输出到不同的日志文件中。
2、日志文件按照文件大小或日期进行切割存储,以避免单一日志文件过大。
3、日志使用简单方便,一次定义全局使用。
建议使用使用Uber-go的ZapLogger,大神李文周大博客已经说的非常明确了,请先参考李老师的博客:
https://www.liwenzhou.com/posts/Go/zap/
问题二和问题三需要补充描述:
一、日志按照级别分文件切割存储
1.1首先实现两个判断日志等级的interface
infoLevel:=zap.LevelEnablerFunc(func(lvlzapcore.Level)bool{
returnlvl>=zapcore.InfoLevel
})
errorLevel:=zap.LevelEnablerFunc(func(lvlzapcore.Level)bool{
returnlvl>=zapcore.ErrorLevel
})
1.2获取info、error日志文件的io.Writer
infoWriter:=getWriter("./logs/demo_info.log")
errorWriter:=getWriter("./logs/demo_error.log")
文件名可拼接入系统时间
funcgetWriter(filenamestring)io.Writer{
//生成rotatelogs的Logger实际生成的文件名demo.log.YYmmddHH
//demo.log是指向最新日志的链接
//保存7天内的日志,每1小时(整点)分割一次日志
hook,err:=rotatelogs.New(
strings.Replace(filename,".log","",-1)+"-%Y%m%d%H.log",//没有使用go风格反人类的format格式
//rotatelogs.WithLinkName(filename),
//rotatelogs.WithMaxAge(time.Hour*24*7),
//rotatelogs.WithRotationTime(time.Hour),
)
iferr!=nil{
panic(err)
}
returnhook
}
1.3最后创建具体的Logger
core:=zapcore.NewTee( zapcore.NewCore(encoder,zapcore.AddSync(infoWriter),infoLevel), zapcore.NewCore(encoder,zapcore.AddSync(errorWriter),errorLevel), )
1.4创建logger
log:=zap.New(core,zap.AddCaller()) errorLogger=log.Sugar()
二、日志定义全局使用
定义完一个logger之后,我们希望整个项目可以拿来即用,不需要在每个文件里都进行初始化,我们使用go函数中的静态函数来实现。
2.1定义一个logger包
2.2定义外部可直接访问的函数
注意函数首字母要大写
funcDebug(args...interface{}){
errorLogger.Debug(args...)
}
funcDebugf(templatestring,args...interface{}){
errorLogger.Debugf(template,args...)
}
funcInfo(args...interface{}){
errorLogger.Info(args...)
}
funcInfof(templatestring,args...interface{}){
errorLogger.Infof(template,args...)
}
funcWarn(args...interface{}){
errorLogger.Warn(args...)
}
funcWarnf(templatestring,args...interface{}){
errorLogger.Warnf(template,args...)
}
funcError(args...interface{}){
errorLogger.Error(args...)
}
funcErrorf(templatestring,args...interface{}){
errorLogger.Errorf(template,args...)
}
funcDPanic(args...interface{}){
errorLogger.DPanic(args...)
}
funcDPanicf(templatestring,args...interface{}){
errorLogger.DPanicf(template,args...)
}
2.3在需要使用的地方直接引入logger包就可以直接使用
logger.Infof("createtokensucc,token=%v",token)
三、源码
3.1文件目录
3.2lgo.go源码
packagelogger
import(
rotatelogs"github.com/lestrrat-go/file-rotatelogs"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"io"
"strings"
"time"
)
varerrorLogger*zap.SugaredLogger
funcinit(){
//设置一些基本日志格式具体含义还比较好理解,直接看zap源码也不难懂
encoder:=zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
MessageKey:"msg",
LevelKey:"level",
EncodeLevel:zapcore.CapitalLevelEncoder,
TimeKey:"ts",
EncodeTime:func(ttime.Time,enczapcore.PrimitiveArrayEncoder){
enc.AppendString(t.Format("2006-01-0215:04:05"))
},
CallerKey:"file",
EncodeCaller:zapcore.ShortCallerEncoder,
EncodeDuration:func(dtime.Duration,enczapcore.PrimitiveArrayEncoder){
enc.AppendInt64(int64(d)/1000000)
},
})
//实现两个判断日志等级的interface
infoLevel:=zap.LevelEnablerFunc(func(lvlzapcore.Level)bool{
returnlvl>=zapcore.InfoLevel
})
errorLevel:=zap.LevelEnablerFunc(func(lvlzapcore.Level)bool{
returnlvl>=zapcore.ErrorLevel
})
//获取info、error日志文件的io.Writer抽象getWriter()在下方实现
infoWriter:=getWriter("./logs/demo_info.log")
errorWriter:=getWriter("./logs/demo_error.log")
//最后创建具体的Logger
core:=zapcore.NewTee(
zapcore.NewCore(encoder,zapcore.AddSync(infoWriter),infoLevel),
zapcore.NewCore(encoder,zapcore.AddSync(errorWriter),errorLevel),
)
log:=zap.New(core,zap.AddCaller())//需要传入zap.AddCaller()才会显示打日志点的文件名和行数,有点小坑
errorLogger=log.Sugar()
}
funcgetWriter(filenamestring)io.Writer{
//生成rotatelogs的Logger实际生成的文件名demo.log.YYmmddHH
//demo.log是指向最新日志的链接
//保存7天内的日志,每1小时(整点)分割一次日志
hook,err:=rotatelogs.New(
strings.Replace(filename,".log","",-1)+"-%Y%m%d%H.log",//没有使用go风格反人类的format格式
//rotatelogs.WithLinkName(filename),
//rotatelogs.WithMaxAge(time.Hour*24*7),
//rotatelogs.WithRotationTime(time.Hour),
)
iferr!=nil{
panic(err)
}
returnhook
}
funcDebug(args...interface{}){
errorLogger.Debug(args...)
}
funcDebugf(templatestring,args...interface{}){
errorLogger.Debugf(template,args...)
}
funcInfo(args...interface{}){
errorLogger.Info(args...)
}
funcInfof(templatestring,args...interface{}){
errorLogger.Infof(template,args...)
}
funcWarn(args...interface{}){
errorLogger.Warn(args...)
}
funcWarnf(templatestring,args...interface{}){
errorLogger.Warnf(template,args...)
}
funcError(args...interface{}){
errorLogger.Error(args...)
}
funcErrorf(templatestring,args...interface{}){
errorLogger.Errorf(template,args...)
}
funcDPanic(args...interface{}){
errorLogger.DPanic(args...)
}
funcDPanicf(templatestring,args...interface{}){
errorLogger.DPanicf(template,args...)
}
funcPanic(args...interface{}){
errorLogger.Panic(args...)
}
funcPanicf(templatestring,args...interface{}){
errorLogger.Panicf(template,args...)
}
funcFatal(args...interface{}){
errorLogger.Fatal(args...)
}
funcFatalf(templatestring,args...interface{}){
errorLogger.Fatalf(template,args...)
}
3.3main函数使用
import(
"flag"
"goAuth/logger"
"goAuth/util"
"os"
)
funcmain(){
createAndCheckToken()
logger.Infof("inmainargs:%v",os.Args)
logger.Errorf("eerror%v","error")
flag.Parse()
logger.Infof("envis%v",*env)
config:=util.InitConfig("./config/"+*env+".conf")
ip:=config["ip"]
port:=config["port"]
envConfig:=config["env"]
logger.Infof("ip=%v,port=%v,env=%v",ip,port,envConfig)
}
总结
以上所述是小编给大家介绍的golangzap日志库使用(含文件切割、分级别存储和全局使用等),希望对大家有所帮助,也非常感谢大家对毛票票网站的支持!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。