仅在调试时启用Boost.Log [英] Enable Boost.Log only on debug

查看:126
本文介绍了仅在调试时启用Boost.Log的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个用于调试的日志记录器,我使用Boost.Log(1.54.0在boost.org首页中有一个补丁)。



我已经创建了一些这样的宏:

  #define LOG_MESSAGE(lvl)BOOST_LOG_TRIVIAL(lvl)

现在的方式是LOG_MESSAGE(lvl)只在调试模式下在BOOST_LOG_TRIVIAL(lvl) / p>

例如:

  LOG_MESSAGE(critical)< 如果我看到这个消息,我们在调试模式


我的第一个尝试是创建一个nullstream ...我认为在发布模式编译器将优化它...

  #if!defined(NDEBUG)
#include< boost / log / trivial.hpp>
#define LOG_MESSAGE(lvl)BOOST_LOG_TRIVIAL(lvl)
#else
#if定义(__GNUC__)
#pragma GCC诊断推送
#pragma GCC诊断忽略 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诊断pop
#endif

#endif


解决方案

日志条目的严重性级别作为水槽的过滤器。接收器将根据严重性级别决定如何处理消息(打印或不打印)。



如果您要不发送邮件,那么您需要重新定义 LOG_MESSAGE 到实际上什么都不做的事情。在Boost库中可能有一些东西,否则,你必须自己编写。也许这将是一个开始:

  class NullLogger 
{
public:
template< ; typename SeverityT> NullLogger(SeverityT){};
template< typename Val> NullLog&运算符<< (const Val&){return * this};
};

...然后:

  #define LOG_MESSAGE(lvl)NullLogger(lvl)

即使没有对日志消息或构成它的表达式进行任何操作,仍会对表达式求值。如果这些表达式中的一些是昂贵的,你仍然会取得性能命中。例如:

  LOG_MESSAGE(debug)< SomeSuperExpensiveFunction(); 

即使您使用上述 NullLogger SomeSuperExpensiveFunction()仍然会被调用。



我建议作为一个替代添加一个标志在运行时评估,并在运行时决定是否进行日志记录:

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

bool 是超级便宜,你可能会发现有一天在未来,打开和关闭记录的能力可能是超级方便。此外,这样做意味着您不需要添加另一个 #define ,这总是一件好事。


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

boolean 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.

这篇关于仅在调试时启用Boost.Log的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆