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

六眼飞鱼酱① 提交于 2020-01-01 12:33:07

问题


Some investigation on existing C/C++ logging solutions turned out that Pantheios might be the best in my case, that is lowest overhead if logging is disabled.

All the loggers seem to support a kind of a print log message. However, in my case I have a function call that should be avoided if logging is disabled (since it's quite expensive).

At the moment I use a very simple logging setup like

#ifdef DEBUG_L1    
cout << "msg 1" << endl // log level 1
#ifdef DEBUG_L2
printBuffer()           // log level 2
#endif
#endif

It serves my needs (for now) since i pay zero overhead if logging is disabled. However the code quickly looks ugly and it is not very flexible.

This should be realized with a C++ logger. As said, the function body of printBuffer() is quite expensive. It would be good if calling it could be avoided if logging is turned off.

Is it possible to declare a whole function call only to be carried out when above a certain log level? Or do i still need the preprocessor in this case?

Edit:

Thanks @BobTFish. I was actually thinking about using the kind of setup you are describing. I am wondering how flexible one can realize this kind of thing. Typically i log a set of strings and values (int, float, and pointers). In the style

cout << "name1=" << int << " name2=" << (void*)(ptr) << endl;

Now, I really do not like switching to a printf like syntax at this point. How would the macro approach deal with this (since it's templated it with just one class parameter)?


回答1:


What me come in mind are c++ specific template based logging frameworks like easylogging or spdlog. In spdlog for example you can create custom log targets by implementing a sink interface. Another (may be the better) option is to use it's log level feature.

Here an example (copied from spdlog manual):

    //
    // 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..");

By implementing the << operator for an own custom class, you can control what data is being dumped to the log. With logger->should_log() you can test if specified log level is enabled.




回答2:


I think you can use Google logging library from here

The typical use of glog with condition

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



回答3:


If you concerned with performance and runtime overhead, take a look at zf_log library. Things you could like about it:

  • It evaluates logging arguments and invokes actual logging function only when necessary (when log level allows that).
  • It has run-time log level AND compile-time log level. LOG() statements below compile-time log level are compiled out and have no run-time overhead.
  • Run-time log level could be changed in run-time, but when message log level is below run-time log level, arguments will not be evaluated and actual log function will not be called. The only thing that will be evaluated is if (msg_log_level >= runtime_log_level).
  • It has extremely small call site (amount of code generated per each LOG() line), 3x-20x times less than other libraries.
  • It doesn't slow down compilation of your sources that include its headers (unlike some header-only libraries).


来源:https://stackoverflow.com/questions/9887822/c-c-logging-facility-that-supports-conditional-function-calls-depending-on-log

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!