C/C++日志记录功能,支持根据日志级别进行的条件函数调用

C/C++ logging facility that supports conditional function calls depending on log-level

本文关键字:日志 函数调用 条件 C++ 记录 功能 支持      更新时间:2023-10-16

对现有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。实际上,我在考虑使用你所描述的那种设置。我想知道一个人能灵活地实现这种事情。通常,我记录一组字符串和值(intfloat和指针)。风格

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倍
  • 它不会减慢包含其标头的源代码的编译速度(与某些仅包含标头的库不同)