文章目录
golang常用库之-日志框架包 zap库、go-log 库、golong日志框架选型
一、日志框架包 zap库
在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能:
- 能够将事件记录到文件中,而不是应用程序控制台。
- 日志切割-能够根据文件大小、时间或间隔等来切割日志文件。
- 支持不同的日志级别。例如INFO,DEBUG,ERROR等。
- 能够打印基本信息,如调用文件/函数名和行号,日志时间等。
1. 什么是zap库
github:https://github.com/uber-go/zap
Zap是非常快的、结构化的,分日志级别的Go日志库。
zap 是 uber 开源的 Go 高性能日志库,支持不同的日志级别, 能够打印基本信息等,但不支持日志的分割,这里我们可以使用 lumberjack 也是 zap 官方推荐用于日志分割,结合这两个库我们就可以实现以下功能的日志机制:
- 能够将事件记录到文件中,而不是应用程序控制台;
- 日志切割能够根据文件大小、时间或间隔等来切割日志文件;
- 支持不同的日志级别,例如 DEBUG , INFO , WARN , ERROR 等;
- 能够打印基本信息,如调用文件、函数名和行号,日志时间等;
2. 为什么选择Uber-go zap
- 它同时提供了结构化日志记录和printf风格的日志记录
- 它非常的快
3. zap库基础
github:https://github.com/uber-go/zap
Zap提供了两种类型的日志记录器—Sugared Logger和Logger。
SugaredLogger提供了debug、info、warn、error、panic、dpanic、fatal这几种方法(使用fmt.Sprint的默认格式),另外还有带f的支持format,带w的方法则支持with键值对。
在性能很好但不是很关键的上下文中,使用SugaredLogger。它比其他结构化日志记录包快4-10倍,并且支持结构化和printf风格的日志记录。
在每一微秒和每一次内存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,内存分配次数也更少,但它只支持强类型的结构化日志记录。
Logger
通过调用zap.NewProduction() | zap.NewDevelopment() | zap.Example()创建一个 Logger。
上面的每一个函数都将创建一个 logger。唯一的区别在于它将记录的信息不同。例如 production logger 默认记录调用函数信息、日期和时间等。
三种创建方式对比:
- Example和Production使用的是json格式输出,Development使用行的形式输出
- Development从警告级别向上打印到堆栈中来跟踪始终打印包/文件/行(方法)在行尾添加任何额外字段作为json字符串以大写形式打印级别名称以毫秒为单位打印ISO8601格式的时间戳
- Production调试级别消息不记录Error,Dpanic级别的记录,会在堆栈中跟踪文件,Warn不会始终将调用者添加到文件中以时间戳格式打印日期以小写形式打印级别名称
通过 Logger 调用 Info/Error 等。
默认情况下日志都会打印到应用程序的 console 界面。
package main
import (
"errors"
"go.uber.org/zap"
)
var logger *zap.Logger
func 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()
}
注意:默认输出为结构化 JSON 结构格式。
Sugared Logger
现在让我们使用 Sugared Logger 来实现相同的功能。
- 大部分的实现基本都相同。
- 惟**一的区别是,我们通过调用主 logger 的. Sugar()**方法来获取一个SugaredLogger
var sugarLogger *zap.SugaredLogger
func main() {
InitLogger()
defer sugarLogger.Sync()
simpleHttpGet("www.baidu.com")
simpleHttpGet("http://www.baidu.com")
}
func InitLogger() {
logger, _ := zap.NewProduction()
sugarLogger = logger.Sugar()
}
func simpleHttpGet(url string) {
sugarLogger.Debugf("Trying to hit GET request for %s", url)
resp, err := http.Get(url)
if err != nil {
sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
} else {
sugarLogger.Infof("Success! statusCode = %s for URL %s", resp.Status, url)
resp.Body.Close()
}
}
注意:默认输出为结构化 JSON 结构格式。
zap.New 和 zapcore.Core 创建 zap.Logger区别
zap.New 是 zap 提供的一个便捷函数,它会帮助创建 Logger 对象。而直接创建 zapcore.Core 更底层一些。
zap.New
// 1. 构建 Config
config := zap.Config{
Level: zap.NewAtomicLevelAt(opts.Level),
Encoding: opts.Format,
EncoderConfig: opts.EncoderConfig,
OutputPaths: opts.OutputPaths,
}
// 2. 使用 zap.New 构建
logger, err := config.Build()
if err != nil {
panic(err)
}
// 3. 替换默认日志
zap.RedirectStdLog(logger)
相比于直接构建 Core 对象,使用 zap.New 具有以下优点:
- 代码更简洁,不需要自己构建 Encoder、WriteSyncer 等
- zap.New 会处理更多细节,构建更可自定义的 Logger
- 更符合 zap 推荐的用法
zap.New 是 zap 提供的一个便捷函数,它会帮助创建 Logger 对象。而直接创建 zapcore.Core 更底层一些。
loggerConfig.Build 和 zapcore.NewCore 区别
loggerConfig.Build 和 zapcore.NewCore 都是可以构建 zap Logger 的方法,但它们的区别在于:
- loggerConfig.Build 是一种更高层的构建方法,通过 LoggerConfig 来配置各种选项,然后构建 Logger。
- zapcore.NewCore 是一种更底层的构建方式,需要自行传入编码器(Encoder)、写入器(WriteSyncer)、日志级别等来组装 Core,然后使用 Core 构建 Logger。
loggerConfig.Build 的优点是使用起来更简单,通过选项配置即可。但自定义程度稍低。
zapcore.NewCore 的优点是自定义程度更高,可以自由组合各种 Core 组件。但使用略微复杂一些。
具体来说:
- loggerConfig.Build 隐藏了编码器和写入器的细节,通过Encoding、OutputPaths等选项一步配置。
- zapcore.NewCore 需要显式传入编码器和写入器对象,自行组装 Core。
- loggerConfig.Build 无法添加自定义的 Core 组件。
- zapcore.NewCore 可以添加自定义的 Core 组件,如 Encoder、WriteSyncer 等。
总结:loggerConfig.Build 适合简单的日志配置需求。
zapcore.NewCore
更适合有复杂自定义需求的场景。
二、go-log 库(go-log包是对zap的封装)
go-ipfs使用的日志库。github地址: https://github.com/whyrusleeping/go-logging
go-log wraps zap to provide a logging facade. go-log manages logging instances and allows for their levels to be controlled individually
Go-log包封装zap以提供日志门面模式。 go-log管理日志记录实例,允许单独控制其级别。
1. 如何使用go-log 库
在logging导入包后,可以创建一个eventLogger实例:
var log = logging.Logger("subsystem name")
可以为所有loggers设置级别:
lvl, err :=