问题
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