显式检查boost :: log过滤器?

时间:2018-05-15 06:58:46

标签: c++ c++11 boost boost-log

我有一些简单的日志记录:

BOOST_LOG_TRIVIAL(trace) << make_trace_record();

现在make_trace_record是一个有点贵的函数(不要问为什么,这很复杂)。我只想在日志当前通过过滤时调用它。我怎样才能做到这一点?我没有看到明确调用严重性过滤器的方法。

3 个答案:

答案 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(); });
}