C ++中混合二进制/文本日志记录的最佳实践

时间:2018-09-04 08:10:54

标签: c++ logging

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

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

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

在启动时(例如00:00:00.001),我们可能要发出一个文本日志条目,内容为“ Employee DB应用程序已启动”。 然后在00:00:00.002,我们收到了一个新的EmployeeInfo,因此我们可能要发出一个包含EmployeeInfo数据的二进制日志条目。

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

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

您的问题不是C ++特有的(可以在Ocaml,Python,Rust,Common Lisp等中使用它)。这取决于习惯,约定,操作系统等。请注意,日志文件主要是常规,并且logrotate之类的实用程序可以管理多个日志文件。