明确检查 boost::log 过滤器?
Check boost::log filter explicitly?
我有一些琐碎的日志记录:
BOOST_LOG_TRIVIAL(trace) << make_trace_record();
现在 make_trace_record
是一个调用起来有点昂贵的函数(不要问为什么,它很复杂)。我只想在日志当前通过过滤时调用它。我怎样才能做到这一点?我没有看到明确调用严重性过滤器的方法。
我会用一个中间人 class 来做这件事,他的 ostream 操作员懒惰地调用你的函数。
像这样:
#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(); });
}
Boost.Log 预先过滤;因此,如果严重性不够高,make_trace_record()
将不会被调用。
为了设置普通记录器的严重性过滤器,请调用:
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::...
);
例如,下面的例子输出1
,表明expensive()
只被调用了一次:
#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
如果想知道它是如何工作的,请查看:
橡子的 correctly points out that Boost.Log macros already implement conditional execution of the streaming expression. This behavior is documented in the Tutorial.
我会补充一点,您可以手动生成日志记录,避免使用宏。举个例子here:
logging::record rec = lg.open_record();
if (rec)
{
logging::record_ostream strm(rec);
strm << "Hello, World!";
strm.flush();
lg.push_record(boost::move(rec));
}
如果日志消息格式很复杂并且不容易适合流表达式,这会很有用。
我有一些琐碎的日志记录:
BOOST_LOG_TRIVIAL(trace) << make_trace_record();
现在 make_trace_record
是一个调用起来有点昂贵的函数(不要问为什么,它很复杂)。我只想在日志当前通过过滤时调用它。我怎样才能做到这一点?我没有看到明确调用严重性过滤器的方法。
我会用一个中间人 class 来做这件事,他的 ostream 操作员懒惰地调用你的函数。
像这样:
#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(); });
}
Boost.Log 预先过滤;因此,如果严重性不够高,make_trace_record()
将不会被调用。
为了设置普通记录器的严重性过滤器,请调用:
boost::log::core::get()->set_filter(
boost::log::trivial::severity >= boost::log::trivial::...
);
例如,下面的例子输出1
,表明expensive()
只被调用了一次:
#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
如果想知道它是如何工作的,请查看:
橡子的
我会补充一点,您可以手动生成日志记录,避免使用宏。举个例子here:
logging::record rec = lg.open_record();
if (rec)
{
logging::record_ostream strm(rec);
strm << "Hello, World!";
strm.flush();
lg.push_record(boost::move(rec));
}
如果日志消息格式很复杂并且不容易适合流表达式,这会很有用。