I need a logger for debug purpose and I'm using Boost.Log (1.54.0 with a patch in the boost.org homepage).
It's all fine I've created some macro like this:
#define LOG_MESSAGE( lvl ) BOOST_LOG_TRIVIAL( lvl )
Now is that a way that LOG_MESSAGE( lvl ) is expaneded in BOOST_LOG_TRIVIAL( lvl ) only in debug mode and ignore in release?
for example:
LOG_MESSAGE( critical ) << "If I read this message we're in debug mode"
edit My first attempt is to create a nullstream... I think that in release mode compiler will optimize it...
#if !defined( NDEBUG )
#include <boost/log/trivial.hpp>
#define LOG_MESSAGE( lvl ) BOOST_LOG_TRIVIAL( lvl )
#else
#if defined( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
#endif
#include <iosfwd>
struct nullstream : public std::ostream {
nullstream() : std::ios(0), std::ostream(0) {}
};
static nullstream g_nullstream;
#define LOG_MESSAGE( lvl ) g_nullstream
#if defined( __GNUC__ )
#pragma GCC diagnostic pop
#endif
#endif
The severity level of the log entry meerly acts as a filter for sinks. The sink will decide what to do with the message (print it or not) based on the severity level. But the message will still be sent.
If you are trying to not send the message at all, then you'll need to redefine LOG_MESSAGE
to something which actually does nothing. there might be something in the Boost library for this, otherwise, you'll have to write your own. Perhaps this will be a start:
class NullLogger
{
public:
template <typename SeverityT> NullLogger (SeverityT) {};
template <typename Val> NullLog& operator<< (const Val&) { return * this};
};
...and then:
#define LOG_MESSAGE (lvl) NullLogger (lvl)
Note however that even though nothing is being done with the log message or the expressions that make it up, the expressions are still evaluated. If some of these expressions are expensive, you will still take the performance hit. For example:
LOG_MESSAGE (debug) << SomeSuperExpensiveFunction();
Even if you are using the NullLogger
above, SomeSuperExpensiveFunction()
is still going to be called.
I would suggest as an alternative adding a flag that is evaluated at runtime, and decide at runtime whether or not to do the logging:
if (mLogStuff)
{
LOG_MESSAGE (debug) << SomeSuperExpensiveFunction();
}
bool
ean comparisons are super cheap, and you may find one day in the future that the ability to turn logging on and off could be super handy. Also, doing this means you don't need to add yet another #define
, which is always a good thing.
I like John's NullLogger
class. The only change I would make is as follows
#define LOG_MESSAGE(lvl) while (0) NullLogger (lvl)
Unfortunately this may generate warnings, but I would hope a decent compiler would then be able to eliminate all the associated logging code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With