golang高性能日志库zap的使用

golang高性能日志库zap的使用本文作者 陈进坚个人博客 https jian1098 github ioCSDN 博客 https blog csdn net c jian 简书 https www jianshu com u 8ba9ac5706b6 联系方式 摘要 zap 是 Uber 开发的非常快的 结构化的 分日志级别的 Go 日志库 根据 Uber goZap 的文档 它的性能比类似的结构化日志包更好 也比标准库更快 具体的性能测试可以去 github 上看到 github 地址 https

摘要

zapUber开发的非常快的、结构化的,分日志级别的Go日志库。根据Uber-go Zap的文档,它的性能比类似的结构化日志包更好,也比标准库更快。具体的性能测试可以去github上看到。

github地址:https://github.com/uber-go/zap

创建实例

通过调用zap.NewProduction()/zap.NewDevelopment()或者zap.Example()创建一个Logger。这三个方法的区别在于它将记录的信息不同,参数只能是string类型

//代码 var log *zap.Logger log = zap.NewExample() log, _ := zap.NewDevelopment() log, _ := zap.NewProduction() log.Debug("This is a DEBUG message") log.Info("This is an INFO message") //Example 输出 { 
   "level":"debug","msg":"This is a DEBUG message"} { 
   "level":"info","msg":"This is an INFO message"} //Development 输出 2018-10-30T17:14:22.459+0800 DEBUG development/main.go:7 This is a DEBUG message 2018-10-30T17:14:22.459+0800 INFO development/main.go:8 This is an INFO message //Production 输出 { 
   "level":"info","ts":.,"caller":"production/main.go:8","msg":"This is an INFO message"} { 
   "level":"info","ts":.,"caller":"production/main.go:9","msg":"This is an INFO message with fields","region":["us-west"],"id":2} 

三种创建方式对比:

  • ExampleProduction使用的是json格式输出,Development使用行的形式输出
  • Development
    • 从警告级别向上打印到堆栈中来跟踪
    • 始终打印包/文件/行(方法)
    • 在行尾添加任何额外字段作为json字符串
    • 以大写形式打印级别名称
    • 以毫秒为单位打印ISO8601格式的时间戳
  • Production
    • 调试级别消息不记录
    • Error,Dpanic级别的记录,会在堆栈中跟踪文件,Warn不会
    • 始终将调用者添加到文件中
    • 以时间戳格式打印日期
    • 以小写形式打印级别名称

格式化输出

zap有两种类型,分别是*zap.Logger*zap.SugaredLogger,它们惟一的区别是,我们通过调用主logger的. Sugar()方法来获取一个SugaredLogger,然后使用SugaredLoggerprintf格式记录语句,例如

var sugarLogger *zap.SugaredLogger func InitLogger() { 
    logger, _ := zap.NewProduction() sugarLogger = logger.Sugar() } func main() { 
    InitLogger() defer sugarLogger.Sync() sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err) } 

写入文件

默认情况下日志都会打印到应用程序的console界面,但是为了方便查询,可以将日志写入文件,但是我们不能再使用前面创建实例的3个方法,而是使用zap.New()

package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" ) var log *zap.Logger func main() { 
    writeSyncer, _ := os.Create("./info.log") //日志文件存放目录 encoderConfig := zap.NewProductionEncoderConfig() //指定时间格式 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder encoder := zapcore.NewConsoleEncoder(encoderConfig) //获取编码器,NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式 core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 log = zap.New(core,zap.AddCaller()) //AddCaller()为显示文件名和行号 log.Info("hello world") log.Error("hello world") } 

日志文件输出结果:

2020-12-16T17:53:30.466+0800 INFO geth/main.go:18 hello world 2020-12-16T17:53:30.486+0800 ERROR geth/main.go:19 hello world 

同时输出控制台和文件

如果需要同时输出控制台和文件,只需要改造一下zapcore.NewCore即可,示例:

package main import ( "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" ) var log *zap.Logger func main() { 
    //获取编码器,NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式 encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式 encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder encoder := zapcore.NewConsoleEncoder(encoderConfig) //文件writeSyncer fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ 
    Filename: "./info.log", //日志文件存放目录 MaxSize: 1, //文件大小限制,单位MB MaxBackups: 5, //最大保留日志文件数量 MaxAge: 30, //日志文件保留天数 Compress: false, //是否压缩处理 }) fileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(fileWriteSyncer,zapcore.AddSync(os.Stdout)), zapcore.DebugLevel) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 log = zap.New(fileCore, zap.AddCaller()) //AddCaller()为显示文件名和行号 log.Info("hello world") log.Error("hello world") } 

文件切割

日志文件会随时间越来越大,为了避免日志文件把硬盘空间占满,需要按条件对日志文件进行切割,zap包本身不提供文件切割的功能,但是可以用zap官方推荐的lumberjack包处理

 //文件writeSyncer fileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ 
    Filename: "./info.log", //日志文件存放目录,如果文件夹不存在会自动创建 MaxSize: 1, //文件大小限制,单位MB MaxBackups: 5, //最大保留日志文件数量 MaxAge: 30, //日志文件保留天数 Compress: false, //是否压缩处理 }) 

按级别写入文件

为了管理人员的查询方便,一般我们需要将低于error级别的放到info.log,error及以上严重级别日志存放到error.log文件中,我们只需要改造一下zapcore.NewCore方法的第3个参数,然后将文件WriteSyncer拆成infoerror两个即可,示例:

package main import ( "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" ) var log *zap.Logger func main() { 
    var coreArr []zapcore.Core //获取编码器 encoderConfig := zap.NewProductionEncoderConfig() //NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式 encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder //按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了 //encoderConfig.EncodeCaller = zapcore.FullCallerEncoder //显示完整文件路径 encoder := zapcore.NewConsoleEncoder(encoderConfig) //日志级别 highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{ 
    //error级别 return lev >= zap.ErrorLevel }) lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { 
    //info和debug级别,debug级别是最低的 return lev < zap.ErrorLevel && lev >= zap.DebugLevel }) //info文件writeSyncer infoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ 
    Filename: "./log/info.log", //日志文件存放目录,如果文件夹不存在会自动创建 MaxSize: 1, //文件大小限制,单位MB MaxBackups: 5, //最大保留日志文件数量 MaxAge: 30, //日志文件保留天数 Compress: false, //是否压缩处理 }) infoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(infoFileWriteSyncer,zapcore.AddSync(os.Stdout)), lowPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 //error文件writeSyncer errorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ 
    Filename: "./log/error.log", //日志文件存放目录 MaxSize: 1, //文件大小限制,单位MB MaxBackups: 5, //最大保留日志文件数量 MaxAge: 30, //日志文件保留天数 Compress: false, //是否压缩处理 }) errorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(errorFileWriteSyncer,zapcore.AddSync(os.Stdout)), highPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 coreArr = append(coreArr, infoFileCore) coreArr = append(coreArr, errorFileCore) log = zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) //zap.AddCaller()为显示文件名和行号,可省略 log.Info("hello info") log.Debug("hello debug") log.Error("hello error") } 

这样修改之后,infodebug级别的日志就存放到info.logerror级别的日志单独放到error.log文件中了

控制台按级别显示颜色

指定编码器的EncodeLevel即可,

 //获取编码器 encoderConfig := zap.NewProductionEncoderConfig() //NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式 encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder //按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了 encoder := zapcore.NewConsoleEncoder(encoderConfig) 

显示文件路径和行号

前面说到要显示文件路径和行号,只需要zap.New方法添加参数zap.AddCaller()即可,如果要显示完整的路径,需要在编码器配置中指定

 //获取编码器 encoderConfig := zap.NewProductionEncoderConfig() //NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式 encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder //按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了 encoderConfig.EncodeCaller = zapcore.FullCallerEncoder //显示完整文件路径 encoder := zapcore.NewConsoleEncoder(encoderConfig) 

完整代码

package main import ( "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" ) var log *zap.Logger func main() { 
    var coreArr []zapcore.Core //获取编码器 encoderConfig := zap.NewProductionEncoderConfig() //NewJSONEncoder()输出json格式,NewConsoleEncoder()输出普通文本格式 encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder //指定时间格式 encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder //按级别显示不同颜色,不需要的话取值zapcore.CapitalLevelEncoder就可以了 //encoderConfig.EncodeCaller = zapcore.FullCallerEncoder //显示完整文件路径 encoder := zapcore.NewConsoleEncoder(encoderConfig) //日志级别 highPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool{ 
    //error级别 return lev >= zap.ErrorLevel }) lowPriority := zap.LevelEnablerFunc(func(lev zapcore.Level) bool { 
    //info和debug级别,debug级别是最低的 return lev < zap.ErrorLevel && lev >= zap.DebugLevel }) //info文件writeSyncer infoFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ 
    Filename: "./log/info.log", //日志文件存放目录,如果文件夹不存在会自动创建 MaxSize: 2, //文件大小限制,单位MB MaxBackups: 100, //最大保留日志文件数量 MaxAge: 30, //日志文件保留天数 Compress: false, //是否压缩处理 }) infoFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(infoFileWriteSyncer,zapcore.AddSync(os.Stdout)), lowPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 //error文件writeSyncer errorFileWriteSyncer := zapcore.AddSync(&lumberjack.Logger{ 
    Filename: "./log/error.log", //日志文件存放目录 MaxSize: 1, //文件大小限制,单位MB MaxBackups: 5, //最大保留日志文件数量 MaxAge: 30, //日志文件保留天数 Compress: false, //是否压缩处理 }) errorFileCore := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(errorFileWriteSyncer,zapcore.AddSync(os.Stdout)), highPriority) //第三个及之后的参数为写入文件的日志级别,ErrorLevel模式只记录error级别的日志 coreArr = append(coreArr, infoFileCore) coreArr = append(coreArr, errorFileCore) log = zap.New(zapcore.NewTee(coreArr...), zap.AddCaller()) //zap.AddCaller()为显示文件名和行号,可省略 log.Info("hello info") log.Debug("hello debug") log.Error("hello error") } 

参考文章

在Go语言项目中使用Zap日志库 – 知乎 (zhihu.com)

[golang高性能日志库zap配置示例 – ExplorerMan – 博客园 (cnblogs.com)](https://zhuanlan.zhihu.com/p/?utm_source=wechat_session)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231457.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 数据库基本操作和常用命令

    1.MySQL数据库2.SQL语句###01数据库概念*A:什么是数据库数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作。*B:什么是数据库管理系统数据库管理系统(DataBaseManagementSystem,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,…

    2022年4月6日
    57
  • C语言 neutralize函数,三种常用分子模拟软件绍.doc

    C语言 neutralize函数,三种常用分子模拟软件绍.doc三种常用分子模拟软件绍三种常用分子模拟软件介绍一、NAMD  NAMD(NAnoscaleMolecularDynamics)是用于在大规模并行计算机上快速模拟大分子体系的并行分子动力学代码。NAMD用经验力场,如Amber,CHARMM和Dreiding,通过数值求解运动方程计算原子轨迹。  1.软件所能模拟的体系的尺度,如微观,介观或跨尺度等  微观。  是众多md软件中并行处理…

    2022年5月25日
    34
  • 市场上Web 应用防火墙哪家好?

    市场上Web 应用防火墙哪家好?伴随着移动互联网及互联网的发展,办公自动化也成为大势所趋。当企业通过网络办公获得无限便利后,也要时刻关注潜在的网络安全威胁。为了保护数据安全,更多企业都会配备Web应用防火墙设备。在市场上的Web应用防火墙产品应用中,被Gartner魔力象限评为Web应用防火墙领导者的F5公司的产品受到了广泛的关注与好评。 F5被Gartner魔力象限评为Web应用防火墙领导者F5推出的WEB应用防…

    2022年5月5日
    35
  • 值得收藏:一份非常完整的 MySQL 规范(一)[通俗易懂]

    值得收藏:一份非常完整的 MySQL 规范(一)

    2022年2月13日
    45
  • 2021韩顺平图解linux_狗剩学习笔记

    2021韩顺平图解linux_狗剩学习笔记韩顺平图解Linux全面升级https://www.bilibili.com/video/BV1Sv411r7vdP001_韩顺平图解Linux全面升级_课程内容20:37P002_韩顺平图解Linux全面升级_应用领域05:05P003_韩顺平图解Linux全面升级_概述16:37P004_韩顺平图解Linux全面升级_Linux与Unix18:09P005_韩顺平图解Linux全面升级_vmware15.5安装17:36P006_韩顺平图解

    2022年5月18日
    41
  • CC2530: ZigBee协议栈实践例程(一)

    CC2530: ZigBee协议栈实践例程(一)1.ZigBee版本      ZigBee是ZigBee联盟建立的技术标准。第一个ZigBee协议栈规范于2004年发布,称为ZigBee2004或者ZigBee1.0;第二个ZigBee协议栈规范于2006年发布,称为ZigBee2006;第三个ZigBee协议栈规范于2007年发布,称为ZigBee2007;然后呢?现在是2018年了。。。2.Z-Stack版本    …

    2022年5月28日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号