-1

我希望我的程序向它的 stderr 写入一个同时是人类和机器可读的日志。

要求:

  1. 日志是消息流。即我不能只写一个大的 xml 或 json 文档。每条消息都必须可以单独解析,而不需要增量解析器或生成器。
  2. 就本问题而言,tty 检测和日志格式选择开关被视为作弊。我希望相同的精确输出同时是人类和机器可读的。
  3. 由于与 2 相同的原因,没有后处理
  4. 没有临时格式。我不希望消费者必须编写解析器。连一点小事都没有。
  5. 没有太晦涩的格式。必须有一个库来解析前 10 种最流行的通用编程语言中的这种格式,并且该库必须能够将整个日志解析为开箱即用的消息流,而无需消费者处理数据。
  • Pretty JSON 失败 5 - 大多数 JSON 解析 API 无法解析多个连接的 JSON 文档。

  • JSON Lines不是人类可读的,尤其是当它包含嵌套数据时,因为整个日志条目最终都在一行上。

  • 看来application/json-seq (RFC 7464)确实允许 JSON 文本打印得很漂亮(人类可读),同时只需要在常规 JSON 解码器之上进行非常简单的解析。这是迄今为止最接近的一个。

验尸

我最终重新考虑了我的方法:记录jsonlines - 最容易生成和使用,使用外部漂亮打印机进行后处理,例如jq .供人类使用。

4

2 回答 2

1

LIFECYCLE

Logging needs to be understood as a lifecycle, where JSON logs are typically used in 2 formats:

  • On a developer PC you use prettified output
  • In deployed systems you use a log entry per line bare format that suits log shippers such as Filebeat
  • Logs are then aggregated from the bare format to a system where they are used by humans in a readable way

The production logs remain human readable - tools such as Kibana allow you to view them in a readable format and ask questions of them.

When you think about the above flow it makes sense, since log storage is efficient and readability is also good. It requires a separation of concerns though.

ONLINE DEMO LOGGING SYSTEM

Feel free to log in to my cloud Elastic Search system at the bottom of this page. Log in to my web app at the top of the page, then query your own API activity in Kibana like this.

My system is a logging design for a microservices platform - see my Effective API Logging blog post in case interested in how it works. A good logging system usually needs an architectural design like this.

于 2021-10-07T13:24:56.553 回答
0

YAML似乎是一个不错的选择。您可以将日志作为独立的 YAML 文档发出,以---[1] 分隔。拥有多个文档是标准的 YAML,这至少得到了我所知道的 YAML 解析器的支持。基本的结构化数据可以在 YAML 中打印在一行中,同时仍然非常易于人类阅读。

https://yaml.org/有一个不同编程语言的实现列表。在stackoverflow 2021 开发者调查[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] ok, that means you have to emit --- every second line or you have to insert it before parsing the document between all lines. If you just emit a --- in every second line, YAML satisfies your fifth requirement.
[2] except for Kotlin, but Kotlin users may use the java library as far as I can see

于 2021-10-06T19:51:13.370 回答