深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)


Posted in Javascript onFebruary 19, 2020

日志处理经常有以下几个需求:

1、不同级别的日志输出到不同的日志文件中。

2、日志文件按照文件大小或日期进行切割存储,以避免单一日志文件过大。

3、日志使用简单方便,一次定义全局使用。

建议使用使用Uber-go的Zap Logger,大神李文周大博客已经说的非常明确了,请先参考李老师的博客:

https://www.liwenzhou.com/posts/Go/zap/

问题二和问题三需要补充描述:

一、日志按照级别分文件切割存储

1.1 首先实现两个判断日志等级的interface

infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
 return lvl >= zapcore.InfoLevel
})

errorLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
 return lvl >= zapcore.ErrorLevel
})

1.2 获取 info、error日志文件的io.Writer

infoWriter := getWriter("./logs/demo_info.log")
errorWriter := getWriter("./logs/demo_error.log")

文件名可拼接入系统时间

func getWriter(filename string) 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),
 )

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

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包

深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)

2.2 定义外部可直接访问的函数

注意函数首字母要大写

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...)
}

2.3 在需要使用的地方直接引入logger 包就可以直接使用

logger.Infof("create token succ , token=%v", token)

三、源码

3.1 文件目录

深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)

3.2 lgo.go 源码

package logger
import (
 rotatelogs "github.com/lestrrat-go/file-rotatelogs"
 "go.uber.org/zap"
 "go.uber.org/zap/zapcore"
 "io"
 "strings"
 "time"
)
var errorLogger *zap.SugaredLogger
func init(){
 // 设置一些基本日志格式 具体含义还比较好理解,直接看zap源码也不难懂
 encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
 MessageKey: "msg",
 LevelKey: "level",
 EncodeLevel: zapcore.CapitalLevelEncoder,
 TimeKey: "ts",
 EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
  enc.AppendString(t.Format("2006-01-02 15:04:05"))
 },
 CallerKey: "file",
 EncodeCaller: zapcore.ShortCallerEncoder,
 EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
  enc.AppendInt64(int64(d) / 1000000)
 },
 })
 // 实现两个判断日志等级的interface
 infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
 return lvl >= zapcore.InfoLevel
 })
 errorLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
 return lvl >= 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()
}
func getWriter(filename string) 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),
 )
 if err != nil {
 panic(err)
 }
 return hook
}
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.3 main 函数使用

import (
 "flag"
 "goAuth/logger"
 "goAuth/util"
 "os"
)

func main() {
 createAndCheckToken()
 logger.Infof("in main args:%v", os.Args)
 logger.Errorf("eerror %v", "error")
 flag.Parse()
 logger.Infof("env is %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)
}

总结

以上所述是小编给大家介绍的golang zap 日志库使用(含文件切割、分级别存储和全局使用等),希望对大家有所帮助,也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
extjs grid设置某列背景颜色和字体颜色的实现方法
Sep 06 Javascript
封装的jquery翻页滚动(示例代码)
Nov 18 Javascript
JavaScript用select实现日期控件
Jul 17 Javascript
JavaScript字符串删除重复字符的方法
Dec 25 Javascript
基于jQuery实现二级下拉菜单效果
Feb 01 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
May 16 Javascript
jquery hover 不停闪动问题的解决方法(亦为stop()的使用)
Feb 10 Javascript
JS中实现函数return多个返回值的实例
Feb 21 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
Aug 15 Javascript
JavaScript-定时器0~9抽奖系统详解(代码)
Aug 16 Javascript
详解ng-alain动态表单SF表单项设置必填和正则校验
Jun 11 Javascript
webpack3升级到webpack4遇到问题总结
Sep 30 Javascript
vue中实现回车键登录功能
Feb 19 #Javascript
Vue中实现回车键切换焦点的方法
Feb 19 #Javascript
整理 node-sass 安装失败的原因及解决办法(小结)
Feb 19 #Javascript
Vue常用的全选/反选的示例代码
Feb 19 #Javascript
详解node和ES6的模块导出与导入
Feb 19 #Javascript
JS实现分页导航效果
Feb 19 #Javascript
vue随机验证码组件的封装实现
Feb 19 #Javascript
You might like
thinkphp 5框架实现登陆,登出及session登陆状态检测功能示例
2019/10/10 PHP
用js实现的自定义的对话框的实现代码
2010/03/21 Javascript
jQuery 常见操作实现方式和常用函数方法总结
2011/05/06 Javascript
Node.js:Windows7下搭建的Node.js服务(来玩玩服务器端的javascript吧,这可不是前端js插件)
2011/06/27 Javascript
基于jquery实现的鼠标滑过按钮改变背景图片
2011/07/15 Javascript
Jquery中LigerUi的弹出编辑框(实现方法)
2013/07/09 Javascript
ExtJS4中的requires使用方法示例介绍
2013/12/03 Javascript
TypeScript Type Innference(类型判断)
2016/03/10 Javascript
Javascript发送AJAX请求实例代码
2016/08/21 Javascript
js遮罩效果制作弹出注册界面效果
2017/01/25 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
vue.js 实现评价五角星组件的实例代码
2018/08/13 Javascript
Vue.js中该如何自己维护路由跳转记录
2019/05/19 Javascript
vue中移动端调取本地的复制的文本方式
2020/07/18 Javascript
vue实现移动端项目多行文本溢出省略
2020/07/29 Javascript
[01:13:18]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
在树莓派2或树莓派B+上安装Python和OpenCV的教程
2015/03/30 Python
Python协程的用法和例子详解
2017/09/09 Python
基于Numba提高python运行效率过程解析
2020/03/02 Python
Python 面向对象静态方法、类方法、属性方法知识点小结
2020/03/09 Python
Django-migrate报错问题解决方案
2020/04/21 Python
Python如何创建装饰器时保留函数元信息
2020/08/07 Python
教师简历自我评价
2014/02/03 职场文书
2014五一国际劳动节活动总结范文
2014/04/14 职场文书
工会换届选举方案
2014/05/21 职场文书
团拜会策划方案
2014/06/07 职场文书
党员目标管理责任书
2014/07/25 职场文书
农村党支部书记党群众路线四风问题整改措施
2014/09/26 职场文书
就业协议书范本
2014/10/08 职场文书
捐助感谢信
2015/01/22 职场文书
学校节水倡议书
2015/04/29 职场文书
银行资信证明
2015/06/17 职场文书
使用Html+Css实现简易导航栏功能(导航栏遇到鼠标切换背景颜色)
2021/04/07 HTML / CSS
对讲机的最大通讯距离是多少
2022/02/18 无线电
win11无线投屏在哪设置? win11无线投屏功能的使用方法
2022/04/08 数码科技
vue @ ~ 相对路径 路径别名设置方式
2022/06/05 Vue.js