是否有人类可读的结构化日志记录格式?
Is there a human readable structured logging fomat?
我希望我的程序将人类和机器同时可读的日志写入其 stderr。
要求:
- 日志是消息流。 IE。我不能只写一个大 xml 或 json 文档。每条消息都必须可以单独解析,而不需要增量解析器或生成器。
- tty detection 和日志格式选择开关被认为是为了这个问题的目的作弊。我希望完全相同的输出同时可供人类和机器阅读。
- 由于与 2
相同的原因,没有进行后处理
- 没有临时格式。我不希望消费者必须编写解析器。甚至不是微不足道的。
- 没有太难懂的格式。必须有一个库来解析前 10 种最流行的通用编程语言中的这种格式 和 该库必须能够将整个日志解析为消息流 开箱即用,无需消费者修改数据。
漂亮 JSON 失败 5 - 大多数 JSON 解析 API 无法解析多个串联的 JSON 文档。
JSON Lines 不是人类可读的,尤其是当它包含嵌套数据时,因为整个日志条目最终都在一行上。
看来 application/json-seq (RFC 7464) 确实允许 JSON 文本打印得漂亮(人类可读),同时只需要在常规 [=54] 之上进行非常简单的解析=]解码器。这是最近的一个。
Post-死亡
我最终重新考虑了我的方法:log jsonlines - easiest to generate and consume, post-process with en external pretty-printer such as jq .
供人类消费。
YAML 似乎是个不错的选择。
您可以将日志作为独立的 YAML 文档发出,以 ---
[1] 分隔。
拥有多个文档是标准的 YAML,这至少得到了我所知道的 YAML 解析器的支持。基本的结构化数据可以在 YAML 中打印在一行中,同时仍然具有很好的人类可读性。
https://yaml.org/ has a list of implementations for different programming languages. There is an implementation for all the top ten programming languages in the Whosebug 2021 developer survey[2].
示例日志
{level: INFO, message: first log message, time: "2021-10-06 21:37", data: [item1, item2, item3]}
--- # document separator (and this is a comment btw)
{level: INFO, message: still logging, time: "2021-10-06 21:38", data: {key1: [nested, data], key2: whatever}}
---
{level: FATAL, message: getting bored, time: "2021-10-06 21:38", data: 0}
[1] 好的,这意味着您必须每隔两行发出一次 ---
,或者您必须在解析所有行之间的文档之前插入它。如果您只是每隔两行发出一个 ---
,YAML 就满足您的第五个要求。
[2] Kotlin 除外,但据我所知,Kotlin 用户可能会使用 java 库
生命周期
日志记录需要理解为一个生命周期,其中 JSON 日志通常以 2 种格式使用:
- 在您使用美化输出的开发人员 PC 上
- 在已部署的系统中,您使用适合 Filebeat 等日志传送器的每行日志条目裸格式
- 然后将日志从裸格式聚合到一个系统中,供人类以可读的方式使用
生产日志保持人类可读性 - Kibana 等工具允许您以可读格式查看它们并提出问题。
当你想到上面的流程时,它是有道理的,因为日志存储是高效的,可读性也很好。不过,它需要关注点分离。
在线演示日志系统
欢迎在this page. Log in to my web app at the top of the page, then query your own API activity in Kibana like this底部登录我的云ElasticSearch系统。
我的系统是微服务平台的日志记录设计 - 如果对其工作原理感兴趣,请参阅我的 Effective API Logging 博客 post。一个好的日志系统通常需要这样的架构设计。
我希望我的程序将人类和机器同时可读的日志写入其 stderr。
要求:
- 日志是消息流。 IE。我不能只写一个大 xml 或 json 文档。每条消息都必须可以单独解析,而不需要增量解析器或生成器。
- tty detection 和日志格式选择开关被认为是为了这个问题的目的作弊。我希望完全相同的输出同时可供人类和机器阅读。
- 由于与 2 相同的原因,没有进行后处理
- 没有临时格式。我不希望消费者必须编写解析器。甚至不是微不足道的。
- 没有太难懂的格式。必须有一个库来解析前 10 种最流行的通用编程语言中的这种格式 和 该库必须能够将整个日志解析为消息流 开箱即用,无需消费者修改数据。
漂亮 JSON 失败 5 - 大多数 JSON 解析 API 无法解析多个串联的 JSON 文档。
JSON Lines 不是人类可读的,尤其是当它包含嵌套数据时,因为整个日志条目最终都在一行上。
看来 application/json-seq (RFC 7464) 确实允许 JSON 文本打印得漂亮(人类可读),同时只需要在常规 [=54] 之上进行非常简单的解析=]解码器。这是最近的一个。
Post-死亡
我最终重新考虑了我的方法:log jsonlines - easiest to generate and consume, post-process with en external pretty-printer such as jq .
供人类消费。
YAML 似乎是个不错的选择。
您可以将日志作为独立的 YAML 文档发出,以 ---
[1] 分隔。
拥有多个文档是标准的 YAML,这至少得到了我所知道的 YAML 解析器的支持。基本的结构化数据可以在 YAML 中打印在一行中,同时仍然具有很好的人类可读性。
https://yaml.org/ has a list of implementations for different programming languages. There is an implementation for all the top ten programming languages in the Whosebug 2021 developer survey[2].
示例日志
{level: INFO, message: first log message, time: "2021-10-06 21:37", data: [item1, item2, item3]}
--- # document separator (and this is a comment btw)
{level: INFO, message: still logging, time: "2021-10-06 21:38", data: {key1: [nested, data], key2: whatever}}
---
{level: FATAL, message: getting bored, time: "2021-10-06 21:38", data: 0}
[1] 好的,这意味着您必须每隔两行发出一次 ---
,或者您必须在解析所有行之间的文档之前插入它。如果您只是每隔两行发出一个 ---
,YAML 就满足您的第五个要求。
[2] Kotlin 除外,但据我所知,Kotlin 用户可能会使用 java 库
生命周期
日志记录需要理解为一个生命周期,其中 JSON 日志通常以 2 种格式使用:
- 在您使用美化输出的开发人员 PC 上
- 在已部署的系统中,您使用适合 Filebeat 等日志传送器的每行日志条目裸格式
- 然后将日志从裸格式聚合到一个系统中,供人类以可读的方式使用
生产日志保持人类可读性 - Kibana 等工具允许您以可读格式查看它们并提出问题。
当你想到上面的流程时,它是有道理的,因为日志存储是高效的,可读性也很好。不过,它需要关注点分离。
在线演示日志系统
欢迎在this page. Log in to my web app at the top of the page, then query your own API activity in Kibana like this底部登录我的云ElasticSearch系统。
我的系统是微服务平台的日志记录设计 - 如果对其工作原理感兴趣,请参阅我的 Effective API Logging 博客 post。一个好的日志系统通常需要这样的架构设计。