zap日志框架
github:zap
Hello World
package main
import (
"time"
"go.uber.org/zap"
)
func main() {
logger := zap.NewExample()
defer logger.Sync() // zap底层 API 可以设置缓存,所以一般使用defer logger.Sync()将缓存同步到文件中
url := "http://example.org/api"
logger.Info("failed to fetch URL",
zap.String("url", url),
zap.Int("attempt", 3),
zap.Duration("backoff", time.Second),
)
}由于fmt.Printf之类的方法大量使用interface{}和反射,会有不少性能损失,并且增加了内存分配的频次。zap为了提高性能、减少内存分配次数,没有使用反射,而且默认的Logger只支持强类型的、结构化的日志。必须使用zap提供的方法记录字段。
比如上述代码中的:
zap为 Go 语言中所有的基本类型和其他常见类型都提供了方法。这些方法的名称也比较好记忆,zap.Type(Type为bool/int/uint/float64/complex64/time.Time/time.Duration/error等)就表示该类型的字段,zap.Typep以p结尾表示该类型指针的字段,zap.Types以s结尾表示该类型切片的字段。如:
zap.Bool(key string, val bool) Field:bool字段zap.Boolp(key string, val *bool) Field:bool指针字段zap.Bools(key string, val []bool) Field:bool切片字段
其他特殊类型:
zap.Any(key string, value interface{}) Field:任意类型的字段zap.Binary(key string, val []byte) Field:二进制串的字段
每个字段都使用方法包裹一层比较繁琐,所以zap提供了SugaredLogger,使用logger.Sugar()即可创建SugaredLogger
SugaredLogger
sugared的含义为糖,SugaredLogger的含义就是对Logger包装了一层语法糖,内部提供两种后缀的方法:
Infow,字段形式输出Infof,printf方式输出
如下:
输出结果:
日志级别
zap共提供5中日志级别,分别为:
DebugInfoWarnError,会打印出堆栈信息Fatal,会打印出堆栈信息,并且调用os.Exit(1)退出程序
运行结果:
预定义配置Logger
zap提供了三个方法,用于快速创建logger:
zap.NewExample():json格式,debug级别,适合用于测试代码中zap.NewDevelopment():console格式,debug级别,人性化显示,用于开发环境zap.NewProduction():json格式,info级别,方便解析,用于生产环境zap.NewNop():不记录任何日志,直接丢弃
选项模式
NewExample()/NewDevelopment()/NewProduction()这 3 个函数可以传入若干类型为zap.Option的选项,从而定制Logger的行为。
option: 输出文件名以及行号
打印日志:
这里,字段caller打印的调用位置是main.go:11行,但是这行一般是打印语句执行的位置,定位到这一行通常没有什么用,需要向前查找。我们可以使用zap.AddCallerSkip(skip int)向上跳 1 层。
项目中一般会对日志框架调用进行封装,这时候,如果打印的行数是日志的行数,总会带来一定的困惑,所以,可以设置向上跳一层,查看方法调用方的行数,这样比较有用。
option: 输出调用堆栈
option: 预设字段
自定义配置Logger
通常情况下,上面的三种配置往往达不到我们的要求,这时通常自定义Logger。使用zap.Config结构体创建一个新的Logger配置,并调用他的Build方法,构建出一个Logger。
zap.Config支持的字段如下:
EncoderConfig的具体信息:
此外,针对各种Encoder,zap提供了一些内置的实现:
全局Logger
为了方便在项目中使用,zap提供了两个全局Logger,分别是
全局的
*zap.Logger对象,可以通过zap.L()获取全局的
*zap.SugaredLogger对象,可以通过zap.S()获取
注意,这两个Logger默认不记录任何日志,因为他们都是调用zap.NewNop()方法生成的,要想使用全局Logger,需要使用zap.ReplaceGlobals(logger)函数替换全局Logger:
输出:
思考:这里可以使用全局Logger来封装项目的统一Logger。建立一个package,存放全局Logger配置,然后暴露统一的日志打印方法,既可以与日志框架分离,又可以集中控制日志配置
最后更新于
这有帮助吗?