说明
- 之前翻译的一个教程(没有备份原地址,梯子被封了)。原地址找到后补上
正文
使用预设的记录器可以节省时间,但如果确定要调整记录器,需要探索自定义记录器的方法
使用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
有疑问加站长微信联系(非本文作者)