【问题标题】:Stripping out static text from log messages and save only variables从日志消息中去除静态文本并仅保存变量
【发布时间】:2020-05-01 12:36:42
【问题描述】:

我知道有一种方法可以从日志消息中删除静态文本,并仅将消息的变量部分保留在内存中。但我不确定它是如何完成的。

举一个具体的例子来说明我的意思:

这是客户端的一些代码:

#include <stdio.h>
#include "my_logging.h"
int main() {
   MY_CUSTOM_LOGGING_TECHNIQUE("This is message %d", int, 1);
   MY_CUSTOM_LOGGING_TECHNIQUE("This is message %d", int, 2);
   return 0;
}

以及应该怎么做:

  1. 编译/构建期间:

在编译/构建期间生成 XML 文件以提供每条消息的 ID:

<xml>

<message params=1>
<id>123456</id>
<text>This is message %d</text>
<param>int</param>
</message>

<message params=1>
<id>456342</id>
<text>This is message %d</text>
<param>int</param>
</message>

</xml>
  1. 在运行期间: 只有消息的 ID 与参数的值一起存储在适当的结构中(此处显示为数组“messages_array”): 消息数组:

  1. 在后处理期间: 在运行时保存的值被迭代并与构建期间保存的 XML 文件结合。此后处理步骤将生成日志文件:

这是消息 1
这是消息 2

我在这里试图解决的主要问题是“不必在运行时将静态文本写入文件。相反,只有消息的 ID 和消息中发送的参数的值。

那么,我该怎么做呢?

【问题讨论】:

  • 必须在 C 或 C++ 中完成吗?还有其他几种语言更好地用于解析文本和生成 XML。
  • @jmq XML 文件不是这里的问题。主要问题是去除静态文本并在运行时仅保存参数的值。

标签: c++ c gcc g++


【解决方案1】:

恐怕如果没有一些额外的预处理/后处理,这在 C 中是不可能的。

一种解决方案是使用__COUNTER__ 宏与-E gcc 参数和后处理相结合,生成XML 文件。看这个例子:

#define MY_LOG(string, ...) logPlaceholder(__COUNTER__, string); logFunction(__VA_ARGS__)

void logPlaceholder(int a, const char* str) {}

void logFunction(int param)
{
    printf("%d\n", param);
}

int main()
{
    MY_LOG("hello%d", 1);
    MY_LOG("world%d", 2);
    return 0;
}

您可以用一些可变参数函数替换logFunction 以接受更多参数。

logPlaceholder 将被优化,因为它是空函数 - 输出二进制文件中不会出现任何字符串。

使用 -E 参数编译时会在标准输出中生成类似这样的内容:

int main()
{
    logPlaceholder(0, "hello%d"); logFunction(1);
    logPlaceholder(1, "world%d"); logFunction(2);
    return 0;
}

当您将 gcc 输出重定向到可以后处理的文件时 - 查找 logPlaceholder 字符串并生成带有消息编号、字符串和所有参数的 XML。

但是__COUNTER__ 是特定于编译器的(非标准),并且对于所有宏都是全局的。

【讨论】:

  • 如果它是特定于编译器的,那完全没问题。
猜你喜欢
  • 2019-02-04
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2015-01-06
相关资源
最近更新 更多