c++ - 从日志消息中去除静态文本并仅保存变量
问题描述
我知道有一种方法可以从日志消息中删除静态文本,并且只将消息的变量部分保留在内存中。但我不确定它是如何完成的。
举一个具体的例子来说明我的意思:
这是客户端的一些代码:
#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;
}
以及应该怎么做:
- 在编译/构建期间:
在编译/构建期间生成 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>
- 在运行时:只有消息的 ID 与参数值一起存储在适当的结构中(此处显示为数组“messages_array”):messages_array:
- 在后处理期间:在运行时保存的值被迭代并与在构建期间保存的 XML 文件相结合。此后处理步骤将生成日志文件:
这是消息 1
这是消息 2
我在这里试图解决的主要问题是“不必在运行时将静态文本写入文件。相反,只有消息的 ID 和消息中发送的参数的值。
那么,我该怎么做呢?
解决方案
恐怕如果没有一些额外的预处理/后处理,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__
是编译器特定的(非标准的)并且对于所有宏都是全局的。
推荐阅读
- python - 无法让 OpenPyXl 删除行
- python - 过滤没有空白列的熊猫
- c++ - c++中带默认参数的函数重载
- python - python脚本有效,但heroku崩溃
- validation - 在 MVC 中,如何验证是否使用动态创建的复选框选中了至少一个复选框?
- linux - 使用 LetsEncrypt 通配符证书签署 CSR
- python - Python:将字符串中的数字乘以常数
- javascript - Antd Upload的Dragger组件上传跨域发生
- highcharts - 如何将自定义多选添加到 highcharts 图例?
- ruby - 使用 Ruby Sequel 插入带有硬编码值的选择