【问题标题】:Best practice for mixed binary/text logging in C++C++ 中混合二进制/文本日志记录的最佳实践
【发布时间】:2018-09-04 08:10:53
【问题描述】:

在 C++ 中,是否有用于记录二进制数据(例如具有预定义格式的 POD 消息)和文本数据(用于信息目的)的日志记录框架?

例如,假设我们有一个 POD 类型

struct EmployeeInfo
{
  unsigned int age;
  char name[80];
}

在启动时(例如 00:00:00.001),我们可能希望发出一条文本日志条目,说明“Employee DB app started”。 然后在 00:00:00.002,我们收到了一个新的 EmployeeInfo,因此我们可能想要发出一个包含 EmployeeInfo 数据的二进制日志条目。

对两种类型的事件使用单个日志文件有一些好处,因为事件之间的顺序关系得以维护。日志文件中条目的格式无关紧要(它不需要是人类可读的),只要给定一个日志文件,很容易编写两个独立的实用程序,一个用于处理(例如漂亮打印)所有 EmployeeInfo文件中的信息,用于处理(例如打印到 cout)其中的所有文本条目。

似乎大多数现有的 C++ 日志框架(例如 g2log、glog、spdlog 等)仅用于生成人类可读的文本日志文件,其用法通常类似于 printf 或输出到流,例如:

LOGD << "Hello %s!" << "World";

实现“一个文件”要求的一个明显方法是简单地为这两个事件设计一个通用的消息格式,例如时间戳+长度+类型+真实数据,然后简单地写入二进制文件。缺点是:1)日志语句的格式可能不像现有的日志框架那样自然,2)我们需要额外的代码,例如我们想要现有日志框架提供的一些功能,例如每天自动轮换日志文件。

我认为混合二进制/文本日志记录应该是一个相对常见的场景,但我似乎找不到任何现有的 C++ 库。欢迎任何建议。谢谢。

【问题讨论】:

  • spdlog 提供每日日志功能,您可以设置自定义格式
  • 如果我需要显示结构的内容,我会重载 operator

标签: c++ logging


【解决方案1】:

我不确定混合二进制和文本日志记录是否常见。我从来没有听说过。

您可能会考虑仅记录文本,但会在该文本中发出一些(可打印的)“标识符”(可能受UUIDs 的启发),它们引用一些其他二进制文件(例如,sqlite 数据库)。所以你会发出Hello from _9oXtCgAbkqv 并在另一个数据库中存储一些与_9oXtCgAbkqv 相关的二进制数据。顺便说一句,“标识符”甚至可能是其他二进制文件中的某个文件偏移量。

顺便说一句,如果您发出任何类型的二进制日志类数据,您需要有一个实用程序来检查该二进制数据。 (对于文本文件,这不是问题,因为标准的文本实用程序,如 Linux 命令 lessgrepawktailheadsplit 就足够了。

而且您的问题不是 C++ 特定的(您可以在 Ocaml、Python、Rust、Common Lisp 等中找到它)。这与习惯、约定、操作系统等有关...请注意,日志文件大多是传统,而像logrotate 这样的实用程序可以管理多个日志文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 2015-06-28
    • 1970-01-01
    • 2018-03-27
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多