当前位置:网站首页>Go语言使用zap日志库
Go语言使用zap日志库
2022-06-22 05:30:00 【weixin_46272577】
安装Zap日志库
go get -u go.uber.org/zap
配置Zap Logger
Zap提供了两种类型的日志记录器—Sugared Logger和Logger。
在性能很好但不是很关键的上下文中,使用SugaredLogger。它比其他结构化日志记录包快4-10倍,并且支持结构化和 printf 风格的日志记录。
在每一微秒和每一次内存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,内存分配次数也更少,但它只支持强类型的结构化日志记录。
Logger
- 通过调用
zap.NewProduction()/zap.NewDevelopment()或者zap.Example()创建一个Logger。 - 上面的每一个函数都将创建一个logger。唯一的区别在于它将记录的信息不同。例如production logger默认记录调用函数信息、日期和时间等。
- 通过Logger调用Info/Error等。
- 默认情况下日志都会打印到应用程序的终端界面。
package main
import (
"go.uber.org/zap"
"net/http"
)
var logger *zap.Logger
func main() {
InitLogger()
// Sync 调用底层Core的 Sync 方法,刷新所有缓冲的日志条目。应用程序应注意在退出之前调用 Sync。
defer logger.Sync()
// 向指定 URL 发送 GET 请求,根据成功或出错结果打印日志信息
simpleHttpGet("www.baidu.com")
simpleHttpGet("http://www.baidu.com")
}
func InitLogger() {
// 通过 zap.NewProduction() 创建一个 logger
logger, _ = zap.NewProduction()
}
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()
}
}

可以看到打印了该日志的级别,花费时间,调用位置,以及我们自定义输出的错误信息。
日志记录器方法的语法:
func (log *Logger) MethodXXX(msg string, fields ...Field)
其中MethodXXX是一个可变参数函数,可以是Info / Error/ Debug / Panic等。每个方法都接受一个消息字符串和任意数量的zapcore.Field 参数。
每个zapcore.Field其实就是一组键值对参数。
Sugared Logger
Sugar 包装了 Logger 以提供更符合人们使用习惯但速度稍慢的 API。对 Logger 进行加糖非常便宜,因此单个应用程序同时使用 Loggers 和 SugaredLoggers 是合理的,在性能敏感代码的边界上在它们之间进行转换。
package main
import (
"go.uber.org/zap"、
"net/http"
)
var sugarLogger *zap.SugaredLogger
func main() {
InitLogger()
// Sync 调用底层Core的 Sync 方法,刷新所有缓冲的日志条目。应用程序应注意在退出之前调用 Sync。
defer sugarLogger.Sync()
// 向指定 URL 发送 GET 请求,根据成功或出错结果打印日志信息
simpleHttpGet("www.baidu.com")
simpleHttpGet("http://www.baidu.com")
}
func InitLogger() {
logger, _ := zap.NewProduction()
sugarLogger = logger.Sugar()
}
func simpleHttpGet(url string) {
resp, err := http.Get(url)
if err != nil {
sugarLogger.Errorf(
"Error fetching url..",
zap.String("url", url),
zap.Error(err))
} else {
sugarLogger.Infof("Success..",
zap.String("statusCode", resp.Status),
zap.String("url", url))
resp.Body.Close()
}
}

定制logger
接下来我们将不使用默认的 zap 配置,而是使用自定义的配置。这主要靠0
func New(core zapcore.Core, options ...Option) *Logger 方法来实现。
New 从提供的 zapcore 构造一个新的 Logger 。如果传递的 zapcore.Core 为 nil,则回退到使用无操作实现。
logger := zap.New(core)
我们现在要替换掉之前的 InitLogger 函数
func InitLogger() {
writeSyncer := getLogWriter()
encoder := getEncoder()
// 需传入Encoder、WriterSyncer、Log Level
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
// 使用zap.New(…)方法来手动传递所有配置
logger := zap.New(core)
sugarLogger = logger.Sugar()
}
// 使用JSON格式写入日志
func getEncoder() zapcore.Encoder {
return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}
// 将日志写到 test.log 文件中
func getLogWriter() zapcore.WriteSyncer {
file, _ := os.Create("./test.log")
return zapcore.AddSync(file)
}

更换写入日志的格式
将 JSON Encoder 更改为普通的 Log Encoder
// 使用不同格式写入日志
func getEncoder() zapcore.Encoder {
//return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
return zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
}

可以看到日志文件中的格式发生了改变,不再是之前的 JSON 格式了
更加详细的配置
我们将要增添如下的配置
- 将时间编码成人能看懂的形式
- 在日志文件中记录日志级别
// 自定义日志格式
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
// ISO8601TimeEncoder 序列化时间。以毫秒为精度的 ISO8601 格式字符串的时间。
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
// CapitalLevelEncoder 将Level序列化为全大写字符串。例如, InfoLevel被序列化为“INFO”。
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
return zapcore.NewConsoleEncoder(encoderConfig)
}
日志增添调用函数的信息
// 添加将调用函数信息记录到日志中的功能。
logger := zap.New(core, zap.AddCaller())

完整代码
package main
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"net/http"
"os"
)
var sugarLogger *zap.SugaredLogger
func main() {
InitLogger()
// Sync 调用底层Core的 Sync 方法,刷新所有缓冲的日志条目。应用程序应注意在退出之前调用 Sync。
defer sugarLogger.Sync()
// 向指定 URL 发送 GET 请求,根据成功或出错结果打印日志信息
simpleHttpGet("www.baidu.com")
simpleHttpGet("http://www.baidu.com")
}
func InitLogger() {
// 写入位置
writeSyncer := getLogWriter()
// 编码格式
encoder := getEncoder()
// 需传入Encoder、WriterSyncer、Log Level
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
// 使用zap.New(…)方法来手动传递所有配置
// 增加 Caller 信息
logger := zap.New(core, zap.AddCaller())
sugarLogger = logger.Sugar()
}
// 自定义日志格式
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
// ISO8601TimeEncoder 序列化时间。以毫秒为精度的 ISO8601 格式字符串的时间。
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
// CapitalLevelEncoder 将Level序列化为全大写字符串。例如, InfoLevel被序列化为“INFO”。
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
return zapcore.NewConsoleEncoder(encoderConfig)
}
// 将日志写到 test.log 文件中
func getLogWriter() zapcore.WriteSyncer {
file, _ := os.Create("./test.log")
return zapcore.AddSync(file)
}
func simpleHttpGet(url string) {
resp, err := http.Get(url)
if err != nil {
sugarLogger.Errorf(
"Error fetching url..",
zap.String("url", url),
zap.Error(err))
} else {
sugarLogger.Infof("Success..",
zap.String("statusCode", resp.Status),
zap.String("url", url))
resp.Body.Close()
}
}
切割日志
执行下面的命令安装Lumberjack
go get -u github.com/natefinch/lumberjack
如果只用一个文件记录日志,那么这个文件会越来越大,最后也不方便定位错误。所以我们需要分割日志,比如按照时间来分割,一个日志文件记录一天的信息。
// 在zap中加入Lumberjack支持
func getLogWriter() zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: "./test.log", // 日志文件的位置
MaxSize: 1, // 以 MB 为单位
MaxBackups: 5, // 在进行切割之前,日志文件的最大大小(以MB为单位)
MaxAge: 30, // 保留旧文件的最大天数
Compress: false, // 是否压缩/归档旧文件
}
return zapcore.AddSync(lumberJackLogger)
}
完整代码
package main
import (
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"net/http"
)
var (
sugarLogger *zap.SugaredLogger
)
func main() {
InitLogger()
defer sugarLogger.Sync() // 刷新流,写日志到文件中
// 循环写入日志,这里为了达到切割要求循环记录了 100000 次
for i := 0; i < 100000; i++ {
sugarLogger.Infof("this is a test")
}
}
func InitLogger() {
writeSyncer := getLogWriter()
encoder := getEncoder()
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
logger := zap.New(core, zap.AddCaller())
sugarLogger = logger.Sugar()
}
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
return zapcore.NewConsoleEncoder(encoderConfig)
}
// 在zap中加入Lumberjack支持
func getLogWriter() zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: "./test.log",
MaxSize: 1, // 以 MB 为单位
MaxBackups: 5, // 在进行切割之前,日志文件的最大大小(以MB为单位)
MaxAge: 30, // 保留旧文件的最大天数
Compress: false, // 是否压缩/归档旧文件
}
return zapcore.AddSync(lumberJackLogger)
}

参考
边栏推荐
- \[\e]0; \[email protected]\h: \w\a\]\[\033[01;32m\]\[email protected]\h\[\033[
- 北京密云区知识产权贯标的好处,补贴5-10万
- A reminder to cross-border sellers who are still "shopping"!
- 《双内核实时系统下各个进程间通信方法的性能分析和测试》
- Innosetup method for judging that the program has run
- How to find the source of goods for novice stores and how to find high-quality sources of goods?
- Pytest (12) -allure common features allure attach、allure. step、fixture、environment、categories
- Jedispool tool class
- QEMU ARM interrupt system architecture
- YARN 应用提交过程
猜你喜欢

数据的存储(进阶)

Graduation season | a new start, no goodbye

Squoosh - Google's free open source image compression tool, reducing the image size by 90%! Support API development calls

OPTEE notes

Cookie setting and reading in C #

毕业季 | 新的开始,不说再见

Summary of knapsack problem

《MATLAB 神经网络43个案例分析》:第28章 决策树分类器的应用研究——乳腺癌诊断

通达OA漏洞分析合集

nacos server 源码运行实现
随机推荐
从“ 平台转型 ”到“ DTC品牌出海 ”,2021趋势何在?
The prediction made ten years ago by the glacier has now been realized by Ali, which is very shocking
搜狗输入法无法输出中文
QEMU ARM interrupt system architecture 2
新手开店货源怎么找,怎么找到优质货源?
JS regular expression to implement the thousands separator
Talk about MySQL's locking rule "hard hitting MySQL series 15"
[graduation season · advanced technology Er] a graduate student's chatter
独立站优化清单丨如何有效提升站内转化率?
Want to put Facebook ads but don't know where to start? This article takes you to know more about
Kubernetes -- setting up an environment using minicube
Conversion between JSON, string and map
Force buckle 33 [search rotation sort array]
A piece of code to solve the problem of automatic disconnection of Google colab
想投放Facebook广告却不知从何入手?此文带你深入了解
Research Report on global and Chinese active Ethernet access device industry demand trend and investment prospect 2022-2027
postmanUtils工具类,模拟postman的get,post请求
P1160 queue arrangement
Online text code comparison tool
毕业季 | 新的开始,不说再见