我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Go语言Zap日志库如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Go语言Zap日志库如何使用

这篇“Go语言Zap日志库如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go语言Zap日志库如何使用”文章吧。

一、日志库选型需要和比较

1.日志库选型需求

  • 日志性能

  • 不同日志级别

  • 可读性(包括日志采集、监控等)

  • 文件切割(不同维度分割)

2.日志库比较

记录一条消息和 10 个字段:

PackageTimeTime % to zapObjects Allocated
⚡ zap2900 ns/op+0%5 allocs/op
⚡ zap (sugared)3475 ns/op+20%10 allocs/op
zerolog10639 ns/op+267%32 allocs/op
go-kit14434 ns/op+398%59 allocs/op
logrus17104 ns/op+490%81 allocs/op
apex/log32424 ns/op+1018%66 allocs/op
log1533579 ns/op+1058%76 allocs/op

使用已经有 10 个上下文字段的记录器记录消息:

PackageTimeTime % to zapObjects Allocated
⚡ zap373 ns/op+0%0 allocs/op
⚡ zap (sugared)452 ns/op+21%1 allocs/op
zerolog288 ns/op-23%0 allocs/op
go-kit11785 ns/op+3060%58 allocs/op
logrus19629 ns/op+5162%70 allocs/op
log1521866 ns/op+5762%72 allocs/op
apex/log30890 ns/op+8182%55 allocs/op

记录一个静态字符串,没有任何上下文或 printf 样式的模板:

PackageTimeTime % to zapObjects Allocated
⚡ zap381 ns/op+0%0 allocs/op
⚡ zap (sugared)410 ns/op+8%1 allocs/op
zerolog369 ns/op-3%0 allocs/op
standard library385 ns/op+1%2 allocs/op
go-kit606 ns/op+59%11 allocs/op
logrus1730 ns/op+354%25 allocs/op
apex/log1998 ns/op+424%7 allocs/op
log154546 ns/op+1093%22 allocs/op

通过上面benchmark测试可以Zap性能是非常出众的。主要是大多数日志库提供的方式是基于反射的序列化和字符串格式化,这种方式代价太高,而 Zap 采取不同的方法。

  • 避免 interface{} 使用强类型设计

  • 封装强类型,无反射

  • 使用零分配内存的 JSON 编码器,尽可能避免序列化开销

二、Zap(Uber-go)

1.安装

go get -u go.uber.org/zap

2.配置Zap Logger

Zap提供了两种类型的日志记录器:Sugared Logger、Logger。在每一微秒和每一次内存分配都很重要的上下文中,使用Logger,内存分配次数也更少,但它只支持强类型的结构化日志记录。对性能不是要求极致,建议使用SugaredLogger,支持结构化和 printf 风格的日志记录。

2.1.Logger
  • 通过调用zap.NewProduction() | zap.NewDevelopment() | zap.Example()创建一个 Logger。

  • 上面的每一个函数都将创建一个 logger。唯一的区别在于它将记录的信息不同。例如 production logger 默认记录调用函数信息、日期和时间等。

  • 通过 Logger 调用 Info/Error 等。

  • 默认情况下日志都会打印到应用程序的 console 界面。

package mainimport ("errors""go.uber.org/zap")var logger *zap.Loggerfunc main() {InitLogger()logger.Debug("这是一条日志", zap.String("name", "zhangSang"), zap.Int("age", 18)) // zap.NewProduction() 默认不输出该级别日志logger.Info("这是一条日志", zap.String("name", "zhangSang"), zap.Int("age", 18))logger.Error("这是一条日志", zap.String("name", "zhangSang"), zap.Error(errors.New("错误信息")))}func InitLogger() {logger, _ = zap.NewProduction()defer logger.Sync()}

上面代码执行结果:

{"level":"info","ts":1655165315.1104648,"caller":"test/main.go:13","msg":"这是一条日志","name":"zhangSang","age":18}
{"level":"error","ts":1655165315.1105008,"caller":"test/main.go:14","msg":"这是 一条日志","name":"zhangSang","error":"错误信息","stacktrace":"main.main\n\tD:/Go/Work/class="lazy" data-src/test/main.go:14\nruntime.main\n\tD:/Go/class="lazy" data-src/runtime/proc.go:255"

2.2.Sugared Logger
  • 基本实现都一样,使用SugaredLogger支持Printf格式记录语句

  • 调用logger的sugar()方法来获取一个SugaredLogger

package mainimport ("errors""go.uber.org/zap")var logger *zap.Loggervar sugar *zap.SugaredLoggerfunc main() {InitLogger()sugar.Debug("这是一条日志", zap.String("name", "zhangSang"), zap.Int("age", 18)) // zap.NewProduction() 默认不输出该级别日志sugar.Info("这是一条日志", zap.String("name", "zhangSang"), zap.Int("age", 18))sugar.Error("这是一条日志", zap.String("name", "zhangSang"), zap.Error(errors.New("错误信息")))}func InitLogger() {logger, _ = zap.NewProduction()defer logger.Sync()sugar = logger.Sugar()}

上面代码执行结果:

{"level":"info","ts":1655165815.3873067,"caller":"test/main.go:14","msg":"这是一条日志{name 15 0 zhangSang <nil>} {age 11 18  <nil>}"}
{"level":"error","ts":1655165815.3880382,"caller":"test/main.go:15","msg":"这是一条日志{name 15 0 zhangSang <nil>} {error 26 0  错误信息}","stacktrace":"main.main\n\tD:/GoWork/class="lazy" data-src/test/main.go:15\nruntime.main\n\tD:/Go/class="lazy" data-src/runtime/proc.go:255"}

2.3. 配置Logger

zap.New()方法来手动传递所有配置,而不是使用像zap.NewProduction()这样的预置方法来创建 logger;zapcore.Core需要三个配置&mdash;&mdash;Encoder,WriteSyncer,LogLevel。

func New(core zapcore.Core, options ...Option) *Logger

Encoder: 编码器 (配置日志格式)。此处使用NewJSONEncoder() (如果不喜欢JSON格式日志,NewConsoleEncoder()指定普通 Encoder),并使用预先设置的ProductionEncoderConfig(),ProductionEncoderConfig()返回一个自定义的EncoderConfig。

func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()return zapcore.NewJSONEncoder(encoderConfig)}

WriterSyncer :指定日志写到何处。使用zapcore.AddSync()函数并且将打开的文件句柄传入。

func getLogWriter() zapcore.WriteSyncer {file, _ := os.OpenFile("./test.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) // 打开文件(不存在创建)return zapcore.AddSync(file)}

3.Log Level-指定日志级别

func InitLogger() {writeSyncer := getLogWriter()encoder := getEncoder()core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) // DebugLevellogger = zap.New(core)defer logger.Sync()sugarLogger = logger.Sugar()}

大家将上面的方法新增测试代码中,运行结果:

Go语言Zap日志库如何使用

4.时间格式化处理

func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = customTimeEncoderreturn zapcore.NewJSONEncoder(encoderConfig)}func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {enc.AppendString(t.Format("2006-01-02 15:04:05.000"))}

运行结果:

Go语言Zap日志库如何使用

5.输出文件名和行号

zap.New()中加上zap.AddCaller()。

func InitLogger() {writeSyncer := getLogWriter()encoder := getEncoder()core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) // DebugLevellogger = zap.New(core, zap.AddCaller())defer logger.Sync()sugarLogger = logger.Sugar()}

运行结果:

Go语言Zap日志库如何使用

三.使用 Lumberjack 进行日志切割归档

1. 安装

go get -u github.com/natefinch/lumberjack

2.Zap logger中使用Lumberjack

func getLogWriter() zapcore.WriteSyncer {lumberJackLogger := &lumberjack.Logger{Filename:   "./test.log", // 日志文件位置MaxSize:    1,            // 进行切割之前,日志文件最大值(单位:MB),默认100MBMaxBackups: 10,           // 保留旧文件的最大个数MaxAge:     1,            // 保留旧文件的最大天数Compress:   false,        // 是否压缩/归档旧文件}return zapcore.AddSync(lumberJackLogger)}

3.完整代码

package mainimport ("github.com/natefinch/lumberjack""go.uber.org/zap""go.uber.org/zap/zapcore""time")var logger *zap.Loggervar sugar *zap.SugaredLoggerfunc main() {InitLogger()for i := 0; i < 99999; i++ {sugar.Debugf("查询用户信息开始 id:%d", 1)sugar.Infof("查询用户信息成功 name:%s age:%d", "zhangSan", 20)sugar.Errorf("查询用户信息失败 error:%v", "未该查询到该用户信息")}}func InitLogger() {writeSyncer := getLogWriter()encoder := getEncoder()core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)logger = zap.New(core, zap.AddCaller())defer logger.Sync()sugar = logger.Sugar()}func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = customTimeEncoderreturn zapcore.NewJSONEncoder(encoderConfig)}func getLogWriter() zapcore.WriteSyncer {lumberJackLogger := &lumberjack.Logger{Filename:   "./test.log", // 日志文件位置MaxSize:    1,            // 进行切割之前,日志文件最大值(单位:MB),默认100MBMaxBackups: 5,            // 保留旧文件的最大个数MaxAge:     1,            // 保留旧文件的最大天数Compress:   false,        // 是否压缩/归档旧文件}return zapcore.AddSync(lumberJackLogger)}func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {enc.AppendString(t.Format("2006-01-02 15:04:05.000"))}

在main()函数中循环9999次输出日志,运行结果:

Go语言Zap日志库如何使用

以上就是关于“Go语言Zap日志库如何使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Go语言Zap日志库如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Go语言Zap日志库如何使用

这篇“Go语言Zap日志库如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go语言Zap日志库如何使用”文章吧。一、日
2023-07-05

Go之Zap日志如何使用

这篇“Go之Zap日志如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go之Zap日志如何使用”文章吧。Log包基本用
2023-07-02

在Go语言项目中怎么使用Zap日志库

本篇内容介绍了“在Go语言项目中怎么使用Zap日志库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在Go语言项目中使用Zap日志库介绍在许多
2023-06-30

Golang定制化zap日志库如何使用

本篇内容主要讲解“Golang定制化zap日志库如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang定制化zap日志库如何使用”吧!为什么需要日志一个产品的诞生一定是因为有需求!新
2023-07-05

怎么在Go语言中使用日志包

这篇“怎么在Go语言中使用日志包”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么在Go语言中使用日志包”文章吧。让我们来看
2023-06-30

如何使用Go语言和Redis实现高效日志处理

如何使用Go语言和Redis实现高效日志处理日志处理是软件开发中一个非常重要的环节,它可以帮助我们快速定位和解决问题,同时也可以监控系统的运行状况。在大型系统中,日志数据量通常非常大,而传统的基于文件的日志处理方式存在一定的瓶颈。本文将介绍
2023-10-27

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录