7

我有以下日志结构:

[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"}

您可以在此日志记录片段中看到五种类型的信息。有日期/时间、日志级别、发生、消息和 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
4

2 回答 2

1

The requested logging style would result in a mix of structured logging (json) and unstructured logging (all other fields in console).

blackgreen's answer should make it possible and its a good hack, but the bigger problem here I think is that you are working against what zap has to offer (Blazing fast, structured, leveled logging in Go.).

Recommended approach would be put everything in json and parse json keys in whatever log viewer you are using. Resuling log structure looks something like:

{"timeStamp": "2018-07-09 11:06:16.003", "level": "INFO", "source": "some_pkg/main.go:232", "msg": "Logging message 1", "pid": 8842, "process": "some_process"}
于 2021-10-05T15:37:02.573 回答
1

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

解释

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

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

无解

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

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

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

黑客

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

pid := 8842
procname := "some_process"

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

将打印:

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

于 2021-07-27T11:32:25.400 回答