【发布时间】:2018-05-15 06:58:46
【问题描述】:
我有一些琐碎的日志记录:
BOOST_LOG_TRIVIAL(trace) << make_trace_record();
现在make_trace_record 是一个调用起来有点昂贵的函数(不要问为什么,它很复杂)。我只想在日志当前通过过滤时调用它。我怎样才能做到这一点?我没有看到显式调用严重性过滤器的方法。
【问题讨论】:
我有一些琐碎的日志记录:
BOOST_LOG_TRIVIAL(trace) << make_trace_record();
现在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
对于那些想知道它是如何工作的人,请查看:How does the "lazy evaluation" of Boost Log's trivial loggers work?
【讨论】:
for 循环,但实际上,诀窍是相同的(请参阅我发布的链接问题)。
【讨论】:
我会使用 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(); });
}
【讨论】: