深入浅析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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。