[uber-zap/part2]自定义记录器
source link: https://studygolang.com/articles/19388?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
说明
- 之前翻译的一个教程(没有备份原地址,梯子被封了)。原地址找到后补上
正文
使用预设的记录器可以节省时间,但如果确定要调整记录器,需要探索自定义记录器的方法
使用zap配置结构体创建记录器
可以使用配置 zap.Config
创建记录器,这是一个结构体,可以使用需要的值填充结构体,然后调用结构体的 .Build()
方法来获取记录器
cfg := zap.Config{...} logger, err := cfg.Build()
需要注意的是: zap.Config
的结构体没有默认值,至少为zap需要的三个设置提供值
-
encoder
: 只需要添加个Encoding:"XXX"
,使用json
就会创建一个JSON的encoder,另一个值是console
-
可以使用结构
zapcore.EncoderConfig
来自定义encoder(几乎肯定必须这样做,因为默认的不是很好用) -
level enabler
:这是一种接口类型,它允许zap确定是否应显示特定级别的消息。在zap配置结构中,可以使用Level字段中的AtomicLevel包装器提供此类型。 -
sink
: 日志的输出目标,可以使用OutputPaths
字段指定多个输出路径,输出讲发送到所有这些文件。像stderr
和stdout
也是可以的
定制encoder
仅仅在配置结构体中设置encoder的类型是不够的,默认情况下, json
仅仅输出日志消息中专门提供的字段。
以下是调用 .Build()
方法时候不会抛出错误的最少配置了
logger, _ := zap.Config{ Encoding: "json", Level: zap.NewAtomicLevelAt(zap.DebugLevel), OutputPaths: []string{"stdout"}, }.Build() logger.Info("This is an INFO message with fileds", zap.String("region", "us-west"), zap.Int("id", 2))
输出
{"region":"us-west","id":2}
可以看出,日志信息没有打印出来!
要在 json encoder
中添加信息,需要特别指定将在输出中具有此值的 json
键
logger, _ := zap.Config{ Encoding: "json", Level: zap.NewAtomicLevelAt(zap.DebugLevel), OutputPaths: []string{"stdout"}, EncoderConfig: zapcore.EncoderConfig{ MessageKey: "message", // <--- }, }.Build() logger.Info("This is an INFO message with fileds", zap.String("region", "us-west"), zap.Int("id", 2))
输出
{"message":"This is an INFO message with fileds","region":"us-west","id":2}
zap
可以像消息中添加更多的元数据,比如: level name
, timestamp
, caller
, stacktrace
等等。除非明确指出与元数据对应的JSON键,否者不会显示。
注意:这些元数据名称必须与encoder匹配,否者zap会出错
示例:
cfg := zap.Config{ Encoding: "json", Level: zap.NewAtomicLevelAt(zap.DebugLevel), OutputPaths: []string{"stdout"}, ErrorOutputPaths: []string{"stderr"}, EncoderConfig: zapcore.EncoderConfig{ MessageKey: "message", // <--- LevelKey: "level", EncodeLevel: zapcore.CapitalLevelEncoder, TimeKey: "time", EncodeTime: zapcore.ISO8601TimeEncoder, CallerKey: "caller", EncodeCaller: zapcore.ShortCallerEncoder, }, } logger, _ := cfg.Build() logger.Info("This is an INFO message with fileds", zap.String("region", "us-west"), zap.Int("id", 2))
输出
{"level":"INFO","time":"2018-10-31T14:59:45.238+0800","caller":"zap_config/main.go:29","message":"This is an INFO message with fileds","region":"us-west","id":2}
encoder 元数据字段的其他选项
每个encoder可以根据需要进行定制,以下是zap提供的不同实现
-
timestamp
可以是ISO8601
格式输出,可以是seconds
,milliseconds
甚至nanoseconds
格式输出 -
level
: 可以是capital
或者lowercase
,它们甚至有colored
选项。需要注意,颜色选项在JSON编码器中没有意义 -
caller
:可以以相对格式short
和绝对格式full
显示
动态改变记录器行为
可以从现有的记录器克隆记录器,并对其行为进行某些修改
-
logger.AddCaller()
添加调用者 -
logger.AddStacktrace()
为给定级别以及以上的消息添加堆栈跟踪 -
logger.Fields()
将指定字段添加到新记录器输出的所有消息中。这种方式相比于在实际日志调用期间指定字段,可以降低内存分配来加快日志记录 -
logger.WrapCore()
允许你修改甚至完全替换记录器中包含的encoder
,level
和sink
。以下是示例
fmt.Printf("\n*** Using a JSON encoder, at debug level, sending output tu stuout, all possible keys specified\n\n") cfg := zap.Config{ Encoding: "json", Level: zap.NewAtomicLevelAt(zapcore.DebugLevel), OutputPaths: []string{"stderr"}, ErrorOutputPaths: []string{"stderr"}, EncoderConfig: zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", EncodeLevel: zapcore.CapitalLevelEncoder, TimeKey: "time", EncodeTime: zapcore.ISO8601TimeEncoder, CallerKey: "caller", EncodeCaller: zapcore.ShortCallerEncoder, }, } logger, _ := cfg.Build() logger.Info("This is an INFO message") fmt.Printf("\n*** Same logger with console loggin enable instead\n\n") logger.WithOptions( zap.WrapCore( func(zapcore.Core) zapcore.Core { return zapcore.NewCore(zapcore.NewConsoleEncoder(cfg.EncoderConfig), zapcore.AddSync(os.Stderr), zapcore.DebugLevel) })).Info("This is an INFO message")
输出
*** Using a JSON encoder, at debug level, sending output tu stuout, all possible keys specified {"level":"INFO","time":"2018-11-01T08:59:12.984+0800","caller":"wrap_core/main.go:35","message":"This is an INFO message"} *** Same logger with console loggin enable instead 2018-11-01T08:59:12.984+0800 INFO wrap_core/main.go:43 This is an INFO message
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK