我有一些简单的日志记录:
BOOST_LOG_TRIVIAL(trace) << make_trace_record();
现在make_trace_record
是一个有点贵的函数(不要问为什么,这很复杂)。我只想在日志当前通过过滤时调用它。我怎样才能做到这一点?我没有看到明确调用严重性过滤器的方法。
答案 0 :(得分:3)
Boost.Log预先过滤;因此,如果严重程度不够高,则不会调用make_trace_record()
。
要为普通记录器设置严重性过滤器,请调用:
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::...
);
例如,以下示例输出1
,显示expensive()
仅被调用一次:
<强> Live On Coliru 强>
#include <iostream>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>
int count = 0;
int expensive()
{
return ++count;
}
int main()
{
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::warning
);
BOOST_LOG_TRIVIAL(error) << expensive();
BOOST_LOG_TRIVIAL(info) << expensive();
std::cout << count << '\n';
return 0;
}
打印:
[2018-05-21 14:33:47.327507] [0x00007eff37aa1740] [error] 1
1
对于那些想知道如何运作的人,请查看:How does the "lazy evaluation" of Boost Log's trivial loggers work?
答案 1 :(得分:3)
Acorn 的answer正确地指出Boost.Log宏已经实现了流表达式的条件执行。 {O-3}}中记录了此行为。
我将补充说,您可以手动生成日志记录,避免使用宏。一个例子是Tutorial:
logging::record rec = lg.open_record();
if (rec)
{
logging::record_ostream strm(rec);
strm << "Hello, World!";
strm.flush();
lg.push_record(boost::move(rec));
}
如果日志消息格式很复杂且不适合流式表达式,则此功能非常有用。
答案 2 :(得分:2)
我会用一个陌生人操作员懒惰地调用你的函数的中间类来做这件事。
这样的事情:
#include <type_traits>
#include <utility>
#include <ostream>
#include <iostream>
namespace detail
{
// an ostreamable object that will stream out the result of a unary function object call
template<class F>
struct lazy_generator
{
void write(std::ostream& os) const
{
os << generator_();
}
friend std::ostream& operator<<(std::ostream& os, lazy_generator const& tr)
{
tr.write(os);
return os;
}
F generator_;
};
}
// construct a lazy_generator
template<class F>
auto lazy_trace(F&& f)
{
return detail::lazy_generator<std::decay_t<F>>({std::forward<F>(f)});
}
// test
int main()
{
extern std::string make_trace_record();
// function pointer
std::clog << lazy_trace(&make_trace_record);
// function object
std::clog << lazy_trace([](){ return make_trace_record(); });
}