我正在构建这样的记录器
config := zap.NewDevelopmentConfig()
logger, err := config.Build()
if err != nil {
log.Fatal(err)
}
想象我有结构请求
type Request {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name`
Surname string `protobuf:"bytes,1,opt,name=surname`
}
在我尝试记录 grpc 请求后,重要的是请求不包含姓氏字段
logger.Infof("got request: %v", log)
输出消息为
got request: name:"Bob"
我想要所有具有零值字段的结构,就像这样
got request: name:"Bob" surname:""
在 zap 中是否有关于数据类型 otput 的任何配置
示例中似乎省略了
logger.Sugar()
— zap.Logger
没有 Infof
方法。
SugaredLogger.Infof
根据 fmt.Sprintf
设置对象格式。您需要实现自己的 Stringer
来自定义表示。鉴于示例结构是生成的 protobuf,您可以嵌入类型:
type wrapper struct {
*pb.Request
}
func (wrapper) String() string {
// custom logic here
}
logger.Infof("got request: %v", wrapper{request})
如果您关心性能,则应该使用
zap.Logger
来代替。
从你的问题来看,你是否总是想包含空字符串值并不清楚。如果您想要它们,请使用 logger.Info(msg, zap.Any("request", request))
。如果不这样做,则实施
zapcore.ObjectMarshaler
而不是
fmt.Stringer
。type wrapper struct {
*pb.Request
}
func (w wrapper) MarshalLogObject(enc zapcore.ObjectEncoder) error {
enc.AddString("name", w.Name)
if w.Surname != "" {
enc.AddString("surname", w.Surname)
}
return nil
}
logger.Info("got request", zap.Object("request", wrapper{request}))
logger.Info("got request (without customization)", zap.Any("request", request))