强制 zap 记录每个结构字段

问题描述 投票:0回答:1

我正在构建这样的记录器

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 的任何配置

go grpc zap
1个回答
0
投票

示例中似乎省略了

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))

© www.soinside.com 2019 - 2024. All rights reserved.