如何向 ZAP 日志条目添加新列/字段?

kbe*_*nda 5 logging go go-zap

我有以下日志记录结构:

[STDERR] 2018-07-09 11:06:16.003    INFO    some_pkg/main.go:232    Logging message 1   {"pid": 8842, "process": "some_process"}
[STDERR] 2018-07-09 11:06:16.006    DEBUG   some_pkg/main.go:291    Logging message 2   {"pid": 8842, "process": "other_process"}
[STDERR] 2018-07-09 11:06:16.009    INFO    some_pkg/main.go:345    Logging message 3   {"pid": 8842, "process": "some_process"}
Run Code Online (Sandbox Code Playgroud)

您可以看到此日志记录片段中有五种类型的信息。有日期/时间、日志级别、发生次数、消息和 JSON 字段([STDERR] 字段除外)。这意味着我的日志记录结构中有五列。我想添加一个带有关键pid进程的新列(来自 JSON)。我应该如何使用 ZAP 编码器和配置来做到这一点?我在 ZAP 文档中没有找到解决方案。

我使用以下代码向日志记录添加字段:

logger = logger.With(zap.Field{Key: "pid", Type: zapcore.Int64Type, Integer: int64(os.Getpid())})

但是 pid 字段的值转到 JSON(您可以在上面看到的内容),我希望在新列中看到它。ZAP 中有一种简单的方法可以做到这一点?

我想要的结构如下与前面的例子:

[STDERR] 2018-07-09 11:06:16.003    INFO    some_pkg/main.go:232    Logging message 1   8842    some_process
[STDERR] 2018-07-09 11:06:16.006    DEBUG   some_pkg/main.go:291    Logging message 2   8836    other_process
[STDERR] 2018-07-09 11:06:16.009    INFO    some_pkg/main.go:345    Logging message 3   8842    some_process
Run Code Online (Sandbox Code Playgroud)

bla*_*een 2

没有一个很好的方法来做到这一点。这个答案提供了一个解释、一个非解决方案和一个黑客。

解释

首先让我澄清一下术语:您所说的日志“列”是 的字段zapcore.Entry,即日志条目。列之间的间距由 字段给出ConsoleSeparatorzapcore.EncoderConfig默认为\t

日志条目的格式化发生在该类型EncodeEntry的方法中consoleEncoder,但您无法自定义其行为:zapcore.Entry是一个结构体,并且该实现中没有可以用来更改记录字段的内容和时间的钩子。向 zap 团队请求这一点可能是值得的。

非解决方案

您剩下的第一个选择是实现您自己的编码器并使用它来构造一个zapcore.Core

enc := &customEncoder{} 
logger := zap.New(zapcore.NewCore(enc, os.Stderr, zap.NewAtomicLevelAt(zap.DebugLevel)))
Run Code Online (Sandbox Code Playgroud)

自定义编码器必须实现zapcore.Encoder. 这带来了许多问题,例如日志条目字段的顺序、堆栈跟踪的可能存在、编码器的配置选项、代码重用等。不值得深入研究所有细节;我只想说,对于这个用例来说,实施起来会非常zapcore.Encoder尴尬,而且可能不值得承担维护负担。

黑客攻击

默认控制台编码器打印的最后一个字段zapcore.EntryMessage. 所以你可以做的是预先格式化消息:

pid := 8842
procname := "some_process"

msg := fmt.Sprintf("Logging message 1\t%d\t%s", pid, procname)
logger.Info(msg)
Run Code Online (Sandbox Code Playgroud)

将打印:

[STDERR] 2018-07-09 11:06:16.003 信息 some_pkg/main.go:232 记录消息 1 8842 some_process