zap日志的基本使用(go必会知识*)
目录
- 日志介绍
- 为什么选择zap日志
- zap的安装
- zap的基本配置
- 自定义logger
- 将JSON Encoder更改为普通的Log Encoder
- 编码配置优化
- 使用Lumberjack进行日志切割归档
- Lumberjack的安装
- zap logger中加入Lumberjack
日志介绍
我们都知道哈,项目在开发阶段,出现问题,我们一般会存日志来进行分析问题,这是非常有效的,上线后更需要依赖日志了,所以查看日志是非常重要的。
那么我们需要怎么样的日志呢?
其实在我们的go语言里面的提供了很多的日志库,但是我们需要一个好的日志能够提供以下几个条件:
- 能打印最基本的信息,例如调用的文件,函数名称,行号,日志时间等等。
- 支持不同的日志级别,例如: info 、 debug 、 error 等等
- 能够将记录的日志保存在文件里面,并且可以根据
时间
或者文件大小
来切割日志文件
而zap就完全满足了,他非常的高效,并且是结构化的,分级的go日志库。
为什么选择zap日志
这个问题好哈!两个点:
- 结构化日志记录并且是printf风格的日志记录
- 真的 非常的快 ,非常的高效,啊哈哈
根据Uber-go Zap的文档,它的性能比类似的结构化日志包更好——也比标准库更快。 以下是Zap发布的基准测试信息
- 记录一条消息和10个字段:
- 记录一个静态字符串,没有任何上下文或printf风格的模板:
- 完虐呀家人们!!!
zap的安装
- 直接用工具导入,或者doc命令导入都可以哦!
go get -u go.uber.org/zap
zap的基本配置
Zap提供了两种类型的日志记录器—
Sugared Logger
和Logger
。在性能很好但不是很关键的上下文中,使用
SugaredLogger
。它比其他结构化日志记录包快4-10倍,并且支持结构化和printf风格的日志记录。在每一微秒和每一次内存分配都很重要的上下文中,使用
Logger
。它甚至比SugaredLogger
更快,内存分配次数也更少,但它只支持强类型的结构化日志记录。
Logger
- 可以通过调用
zap.NewProduction()
/zap.NewDevelopment()
来创建又给Logger
- 两种方式都可以,区别就是打印出来的格式不一样
NewDevelopment 是以 空格分开
的形式展示
NewProduction 使用的是 json格式
,键值对的形式
展示出来
- 注意:默认情况下日志都会打印到应用程序的console界面。
SugaredLogger
- 这个就直接使用logger.Sugar()即可,啥使用都管用
- 他们基本上相同,唯一的不同的就是SugaredLogger可以用printf格式记录语句
例如:
sugarLogger.Infof("Success! statusCode = %s for URL %s", resp.Status, url)
自定义logger
那么不想打印在终端怎么办呢,那我们只有自定义配置了
- 那我们只能使用
zap.New(…)
方法来手动传递所有配置
- 我们可以看到需要一个zapcore.Core的参数,所以我们再进去看看
- 我们可以看到这个是一个接口,里面有个newCore的方法可以创建一个core。
- 源码里面可以明显的看到哈,只要我们给三个参数,就可以得到一个logger了,那么这三个参数分别表示上面呢?
Encoder
: 编码器(如何写入日志)。我们将使用开箱即用的NewJSONEncoder(),并使用预先设置的ProductionEncoderConfig()。
// core 三个参数之 编码
func getEncoder() zapcore.Encoder {return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}
WriteSyncer
: 指定日志将写到哪里去。但是打开的类型不一样,文件打开的是io.writer类型,而我们需要的是WriteSyncer,所以我们使用zapcore.AddSync()函数来进行一个转换。
// core 三个参数之 路径
func getLogWriter() zapcore.WriteSyncer {file,_ := os.Create("E:/test.log")return zapcore.AddSync(file)
}
LevelEnabler
: 这个就是我们所需要打印的日志等级设置了,通过它来动态的保存日志,比如上线后我们error以下的日志就不打印了!
- 我们通过 zapcore.***Level 来设置,里面都是封装好的日志等级
- 可以看下zapcore的源码哦
- 非常的ok!然后我们就可以创建一个logger了
var logger *zap.Logger
var sugarLogger *zap.SugaredLoggerfunc InitLogger() {encoder := getEncoder()writerSyncer := getLogWriter()core := zapcore.NewCore(encoder,writerSyncer,zapcore.DebugLevel)logger = zap.New(core)sugarLogger = logger.Sugar()
}func getEncoder() zapcore.Encoder {return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}func getLogWriter() zapcore.WriteSyncer {file,_ := os.Create("E:/test.log")return zapcore.AddSync(file)
}
- 我们来跑一个例子:
- 好用!!!只有存在文件里面才方便我们往后的查看呢!!!
将JSON Encoder更改为普通的Log Encoder
- 我们采用编码格式的时候,采用的json格式满,可以有的人习惯看空格呀,怎么办,那就换一个呗,
- 人家zap也是提供了的
// core 三个参数之 编码
func getEncoder() zapcore.Encoder {return zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
}
- 非常的ok哈!!!
- 但是这个时间,,,还是有点不敬人意哈,所以我们好需要调整以下
编码配置优化
- 那么我们就需要对
encoderConfig
进行一个自定义配置了
func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoderencoderConfig.EncodeLevel = zapcore.CapitalLevelEncoderreturn zapcore.NewConsoleEncoder(encoderConfig)
}
- 修改时间编码器
- 在日志文件中使用大写字母记录日志级别
- 是不是感觉又好很多了!
- 那么我们怎么来获取 调用的文件,函数名称,行号呢?
- 也很简单哈,我们再new一个zap 的时候加个
zap.AddCaller()
即可!
logger := zap.New(core, zap.AddCaller())
- 来看看效果吧!
- 这样子,我们基本上就可以进行一个很好的使用体验了哈!!!
- 你以为没了? 不,还有最重要的一点,
文件的切割
,但是很可惜,zap没有这玩意,所以我们只有采用第三方库来实现拉!
使用Lumberjack进行日志切割归档
注意:Zap本身不支持切割归档日志文件
- 为了实现切割功能呢,我们采用第三方库
Lumberjack
Lumberjack的安装
- 老规矩哈,要是有依赖漏了就 go mod tidy 一下哈!!!
go get -u github.com/natefinch/lumberjack
zap logger中加入Lumberjack
- 要在zap中加入Lumberjack支持,我们需要修改WriteSyncer代码。我们将按照下面的代码修改getLogWriter()函数:
func getLogWriter() zapcore.WriteSyncer {lumberJackLogger := &lumberjack.Logger{Filename: "./test.log",MaxSize: 10,MaxBackups: 5,MaxAge: 30,Compress: false,}return zapcore.AddSync(lumberJackLogger)
}
- 分别表示上面意思呢?
Lumberjack Logger采用以下属性作为输入:
属性 | 含义 |
---|---|
Filename | 日志文件的位置,也就是路径 |
MaxSize | 在进行切割之前,日志文件的最大大小(以MB为单位) |
MaxBackups | 保留旧文件的最大个数 |
MaxAges | 保留旧文件的最大天数 |
Compress | 是否压缩/归档旧文件 |
到这里我们的代码就完成了!!!
来看看总代码:
package mainimport ("github.com/natefinch/lumberjack""go.uber.org/zap""go.uber.org/zap/zapcore""net/http"
)var logger *zap.Logger
var sugarLogger *zap.SugaredLoggerfunc InitLogger() {encoder := getEncoder()writerSyncer := getLogWriter()core := zapcore.NewCore(encoder,writerSyncer,zapcore.DebugLevel)logger = zap.New(core,zap.AddCaller())sugarLogger = logger.Sugar()
}// core 三个参数之 编码
func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoderencoderConfig.EncodeLevel = zapcore.CapitalLevelEncoderreturn zapcore.NewConsoleEncoder(encoderConfig)
}// core 三大核心之 路径
func getLogWriter() zapcore.WriteSyncer {lumberJackLogger := &lumberjack.Logger{Filename: "E:/test.log",MaxSize: 10,MaxBackups: 5,MaxAge: 30,Compress: false,}return zapcore.AddSync(lumberJackLogger)
}func main() {InitLogger()defer logger.Sync()simpleHttpGet("www.baidu.com")simpleHttpGet("http://www.baidu.com")
}
func simpleHttpGet(url string) {resp, err := http.Get(url)if err != nil {logger.Error("Error fetching url..",zap.String("url", url),zap.Error(err))} else {logger.Info("Success..",zap.String("statusCode", resp.Status),zap.String("url", url))resp.Body.Close()}
}
- 这里我们设置的是
日志文件每 5MB 会切割并且在当前目录下最多保存 5 个备份
,并且会将旧文档保存30天。
到这里,我们就完成了zap日志程序集成到项目中了,还是很方便简单的哈!
至于测试数据,大家可以跑几个 goroutine来试试,把MaxSize调小一点,即可看到切分的效果哦!!
zap日志的基本使用(go必会知识*)相关推荐
- zap日志写入通道被覆盖
描述 实现了一个io.Writer接口,允许zap日志写入,传递给界面,出现了日志被覆盖.重复的情况. 原因 io.Writer的接口Write传入的[]byte真实类型是slice.通道传递slic ...
- go zap日志库的使用,以及封装。
go zap日志库使用说明 及 封装 1 zap日志的基本使用 1.0 zap简介 1.1 日志介绍 1.2 为什么选择zap日志 1.3 zap的安装 1.4 创建实例-两种类型 1.4.1 Log ...
- 一文告诉你如何用好uber开源的zap日志库
1. 引子 日志在后端系统中有着重要的地位,通过日志不仅可以直观看到程序的当前运行状态,更重要的是日志可以在程序发生问题时为开发人员提供线索. 在Go生态中,logrus[2]可能是使用最多的Go日志 ...
- go语言 gin框架中集成zap日志库
在go语言gin框架中,日志是默认输出到终端的,但是我们在实际工作中,一般来说是需要记录服务器日志的.而最常用的日志库就是zap日志库,我们需要将gin在终端输出的内容通过zap日志库记录到文件中,首 ...
- Go开发中配置一个Logger日志的功能实现(结合zap日志库)
为什么需要Logger 一般在开发项目的时候我们都是需要一个存储日志的文件,因为在部署项目以后,我们只能通过去筛查日志进行检索问题,这时候日志是否可以呈现清晰这个对于我们进行排查工作是十分重要的,所以 ...
- ZAP日志框架lumberjack日志归档库的分析使用
本次我们从官方例程的角度出发,来分析学习如何让zap日志框架动起来 一. Zap官方例程 1.加糖版 logger, _ := zap.NewProduction() defer logger.Syn ...
- 【Go进阶】如何让你Go项目中日志清晰有趣-Zap日志库
本文先介绍了Go语言原生的日志库的使用,然后详细介绍了非常流行的Uber开源的zap日志库,同时介绍了如何搭配Lumberjack实现日志的切割和归档. Zap日志库在Go语言项目中的使用 在许多Go ...
- Go 语言中的 logger 和 zap 日志库
目录 Go 语言中的 logger 和 zap 日志库 Go Logger Zap Logger Logger Sugared Logger 定制 Logger 记录到文件中 Zap logger 中 ...
- go.uber.org/zap日志库
文章目录 go.uber.org/zap日志库 1.GO SDK里Logger优缺点 2.介绍Uber-go zap 3.安装zap依赖 4.zap.NewProductionEncoderConfi ...
最新文章
- 分布式概念-中心化副本控制机制
- 2月第4周中国五大顶级域名总量减1.8万 美国增10.8万
- (字符串的处理4.7.22)POJ 3337 Expression Evaluator(解析C风格的字符串)
- sql union 语句 case语句
- 蓝牙驱动卸载后自动安装_智能产品 | 安装水循环系统后,全自动洗车机洗车会更节水吗?...
- ebs 供应商地点信息_EBS标准的查看供应商地址
- mac 完全卸载vscode
- html%2b怎么转换成加号,Apache mod_rewrite%2B和加号(+)符号
- 啊哈,算法!为什么你如此“谜”人!
- 最新狼人杀休闲游戏微信小程序模板源码分享
- ArcGIS按属性选择多个地类
- 会员卡管理系统从哪些方面解决门店会员营销困扰?
- 测试质量体系搭建--测试团队目标
- 51单片机--外部中断
- IDEA 学生注册成功并使用一段时间,还要激活,并且提示No suitable licenses associated with account
- 异步电机变压变频控制(Asynchronous VVVF)-恒压频比控制Simulink仿真
- 考研数学 概率论争议题 [Python验证版]
- 华为云的obs工具包类
- 连锁加盟与直营连锁有什么区别?
- 一揽子解决dns错误
热门文章
- 9.8日金证股份前端,得分48分
- Linux 4.15 rc7,深度操作系统 15.4 RC更新详情
- fpga的jtag接口扫不到器件_FPGA中AS和JTAG接口的使用
- Postgresql 获取最新的序列值,并组装成更新序列值的语句
- 【通俗易懂】现场总线与工业以太网
- FullCalendarDemo5 控件的实例讲解—拖拽实现值班排班(五)
- 机电传动控制与其他课程间的关系
- FastAdmin插件开发辅助增强插件
- 理解逻辑回归中的后验概率和损失函数
- 初一一年级计算机试题,计算机一年级《文字录入》期末考试题(理论)A