支持条件函数调用的C / C ++日志记录工具,具体取决于日志级别

时间:2012-03-27 10:32:01

标签: c++ logging c-preprocessor

对现有 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类似语法。宏方法将如何处理这个问题(因为它只用一个类参数来模仿它)?

3 个答案:

答案 0 :(得分:2)

我想到的是基于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;&lt;对于自己的自定义类的运算符,您可以控制将哪些数据转储到日志中。使用logger->should_log(),您可以测试是否启用了指定的日志级别。

答案 1 :(得分:1)

我认为您可以使用here

中的Google日志记录库

条件

的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();
}

答案 2 :(得分:1)

如果您担心性能和运行时开销,请查看zf_log库。你可以喜欢的事情:

  • 它仅评估日志记录参数并在必要时调用实际日志记录函数(当日志级别允许时)。
  • 它具有运行时日志级别和编译时日志级别。编译时日志级别以下的LOG()语句被编译出来并且没有运行时开销。
  • 运行时日志级别可以在运行时更改,但是当消息日志级别低于运行时日志级别时,将不会评估参数并且不会调用实际日志功能。唯一要评估的是if (msg_log_level >= runtime_log_level)
  • 它的呼叫站点非常小(每条LOG()行生成的代码量),比其他库少3到20倍。
  • 它不会减慢包含其标题的源代码的编译速度(与某些仅限标题的库不同)。