我需要一个用于调试目的的记录器,我正在使用Boost.Log(1.54.0和boost.org主页中的补丁)。
一切都很好我已经创建了这样的宏:
#define LOG_MESSAGE( lvl ) BOOST_LOG_TRIVIAL( lvl )
现在只有在调试模式下才能在BOOST_LOG_TRIVIAL(lvl)中显示LOG_MESSAGE(lvl)并在发布时忽略它吗?
例如:
LOG_MESSAGE( critical ) << "If I read this message we're in debug mode"
修改的 我的第一次尝试是创建一个nullstream ...我认为在发布模式下编译器会优化它...
#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
答案 0 :(得分:6)
日志条目的严重性级别仅作为接收器的过滤器。接收器将根据严重性级别决定如何处理消息(打印与否)。但邮件仍然会被发送。
如果您尝试根本不发送消息,那么您需要将LOG_MESSAGE
重新定义为实际上什么都不做的事情。 Boost库中可能有一些东西,否则,你必须自己编写。也许这将是一个开始:
class NullLogger
{
public:
template <typename SeverityT> NullLogger (SeverityT) {};
template <typename Val> NullLog& operator<< (const Val&) { return * this};
};
......然后:
#define LOG_MESSAGE (lvl) NullLogger (lvl)
但请注意,即使没有对日志消息或构成它的表达式进行任何操作,表达式仍会被评估。如果其中一些表达式很昂贵,您仍然会受到性能影响。例如:
LOG_MESSAGE (debug) << SomeSuperExpensiveFunction();
即使您使用上面的NullLogger
,仍然会调用SomeSuperExpensiveFunction()
。
我建议另外添加一个在运行时评估的标志,并在运行时决定 是否进行日志记录:
if (mLogStuff)
{
LOG_MESSAGE (debug) << SomeSuperExpensiveFunction();
}
bool
ean比较超级便宜,您可能会发现将来有一天能够打开和关闭登录功能非常方便。此外,这样做意味着您不需要添加另一个#define
,这总是一件好事。
答案 1 :(得分:3)
我喜欢John的NullLogger
课程。我要做的唯一改变如下
#define LOG_MESSAGE(lvl) while (0) NullLogger (lvl)
不幸的是,这可能会产生警告,但我希望一个不错的编译器能够消除所有相关的日志代码。
答案 2 :(得分:0)
John 的 Public Const _
xupv = 1 _
, xvet = 2 _
, xhid = 3 _
, xban = 4 _
, xrep = 5 _
, xech = 6 _
, xvus = 7 _
, xfDpth = 8 _
, xEds = 9
类在 MSVC 上无法正确编译,并且仍然需要 NullLogger
的 Boost 依赖项,而实际上并不需要。
我提议对类进行以下更改:
SeverityT