C/C++日志记录功能,支持根据日志级别进行的条件函数调用
C/C++ logging facility that supports conditional function calls depending on log-level
对现有C/C++日志记录解决方案的一些调查表明,在我的情况下,Pantheios可能是最好的,如果禁用日志记录,这是最低的开销。
所有的记录器似乎都支持一种打印日志消息。然而,在我的情况下,如果日志记录被禁用,应该避免函数调用(因为它非常昂贵)。
目前,我使用一个非常简单的日志设置,如
#ifdef DEBUG_L1
cout << "msg 1" << endl // log level 1
#ifdef DEBUG_L2
printBuffer() // log level 2
#endif
#endif
它满足了我的需求(目前),因为如果禁用日志记录,我将不支付任何开销。然而,代码很快看起来很难看,而且不是很灵活。
这应该用C++记录器来实现。如上所述,printBuffer()
的功能体相当昂贵。如果在关闭日志记录的情况下可以避免调用它,那就太好了
是否可以声明整个函数调用仅在高于特定日志级别时执行?或者在这种情况下我还需要预处理器吗?
编辑:
谢谢@BobTFish。实际上,我在考虑使用你所描述的那种设置。我想知道一个人能灵活地实现这种事情。通常,我记录一组字符串和值(int
、float
和指针)。风格
cout << "name1=" << int << " name2=" << (void*)(ptr) << endl;
现在,我真的不喜欢在这一点上切换到类似printf
的语法。宏方法将如何处理这一问题(因为它只使用一个类参数对其进行了模板化)?
我想到的是特定于c++的基于模板的日志记录框架,如easylogging或spdlog。例如,在spdlog中,您可以通过实现接收器接口来创建自定义日志目标。另一个(可能更好)选项是使用它的日志级别功能。
这里有一个例子(复制自spdlog手册):
//
// Runtime log levels
//
spd::set_level(spd::level::info); //Set global log level to info
console->debug("This message shold not be displayed!");
console->set_level(spd::level::debug); // Set specific logger's log level
console->debug("Now it should..");
通过实现<lt;运算符,您可以控制将哪些数据转储到日志中。使用logger->should_log()
,您可以测试是否启用了指定的日志级别。
我认为你可以从这里使用谷歌日志库
带条件的glog的典型使用
#include <glog/logging.h>
{
// Initialize logging. There are multiple options, so read the documentation
google::InitGoogleLogging();
void* p;
LOG_IF(INFO, p == nullptr) << "We have nullptr. Bomb detected!";
// Don't forget to shut that down
google::ShutdownGoogleLogging();
}
如果您关心性能和运行时开销,请查看zf_log库。你可以喜欢的东西:
- 它评估日志记录参数,并仅在必要时(当日志级别允许时)调用实际的日志记录函数
- 它具有运行时日志级别和编译时日志级别。编译时日志级别以下的
LOG()
语句是编译出来的,并且没有运行时开销 - 运行时日志级别可以在运行时更改,但当消息日志级别低于运行时日志等级时,将不会计算参数,也不会调用实际的日志函数。唯一要评估的是
if (msg_log_level >= runtime_log_level)
- 它的调用站点非常小(每
LOG()
行生成的代码量),是其他库的3x-20x倍 - 它不会减慢包含其标头的源代码的编译速度(与某些仅包含标头的库不同)
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 根据全局日志级别优化日志函数调用
- 输出函数调用日志文件
- C/C++日志记录功能,支持根据日志级别进行的条件函数调用