Enable Boost.Log for debugging only.

I need a logger for debugging, and I use Boost.Log (1.54.0 with a patch on the boost.org home page).

Everything is fine, I created a macro like this:

#define LOG_MESSAGE( lvl ) BOOST_LOG_TRIVIAL( lvl ) 

Now is this the way that LOG_MESSAGE (lvl) expands to BOOST_LOG_TRIVIAL (lvl) only in debug mode and is ignored in the version?

eg:

 LOG_MESSAGE( critical ) << "If I read this message we're in debug mode" 

edit My first attempt is to create a zero thread ... I think in release mode the compiler optimizes 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 
+4
source share
2 answers

The severity level of the log entries acts as a filter for receivers. The sink will decide what to do with the message (type it or not) depending on the severity level. But the message will still be sent.

If you are not trying to send a message at all, you need to redefine LOG_MESSAGE to actually do nothing. there may be something in the Boost library for this, otherwise you will have to write your own. Perhaps this will be the beginning:

 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 that although nothing is done with the log message or the expressions that make up it, the expressions are still evaluated. If some of these expressions are expensive, you will still get a performance hit. For instance:

 LOG_MESSAGE (debug) << SomeSuperExpensiveFunction(); 

Even if you use the NullLogger above, SomeSuperExpensiveFunction() will still be called.

I would suggest, as an alternative, add a flag that evaluates at runtime and decide at runtime whether the log should be kept:

 if (mLogStuff) { LOG_MESSAGE (debug) << SomeSuperExpensiveFunction(); } 

bool Comparing ean is very cheap, and in the future you may find that turning logging on and off can be very convenient. In addition, this means that you do not need to add another #define , which is always good.

+5
source

I like the John NullLogger class. The only change I would make is as follows

 #define LOG_MESSAGE(lvl) while (0) NullLogger (lvl) 

Unfortunately, this may raise warnings, but I hope that a decent compiler will be able to eliminate all related logging protocols.

+3
source

Source: https://habr.com/ru/post/1490948/


All Articles