显式检查提升::日志过滤器?

Check boost::log filter explicitly?

本文关键字:日志 过滤器 检查      更新时间:2023-10-16

我有一些琐碎的日志记录:

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

对于那些想知道它是如何工作的人,看看: Boost Log 的琐碎记录器的"懒惰评估"是如何工作的?

Acorn的回答正确地指出,Boost.Log 宏已经实现了流表达式的条件执行。本教程中记录了此行为。

我要补充一点,您可以手动生成日志记录,避免使用宏。这里给出了一个例子:

logging::record rec = lg.open_record();
if (rec)
{
logging::record_ostream strm(rec);
strm << "Hello, World!";
strm.flush();
lg.push_record(boost::move(rec));
}

如果日志消息格式很复杂并且不容易适应流式处理表达式,这可能很有用。

我会用一个中间类来做这件事,他的 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(); });
}