Boost.Log-日志消息被意外过滤掉

时间:2019-02-05 13:22:59

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

我正在尝试通过可配置的严重性级别创建过滤器。我编写了以下过滤器类:

class FilterBySeverity
{
public:
    FilterBySeverity(boost::log::trivial::severity_level logLevel) :
        m_logLevel(logLevel),
        m_severityAttributeName("Severity")
    {
    }

    bool operator()(const boost::log::attribute_value_set& attrs) const noexcept
    {
        auto it = attrs.find(m_severityAttributeName);
        if (it == attrs.end()) return true;
        return it->second.extract<int>() >= m_logLevel;
    }

private:
    const boost::log::trivial::severity_level m_logLevel;
    const boost::log::attribute_name m_severityAttributeName;
};

然后我按以下方式初始化日志:

auto sink = boost::log::add_console_log(std::cout);
sink->set_filter(FilterBySeverity(logOptions.m_severity));
sink->locked_backend()->auto_flush(true);

然后我要进行测试输出:

BOOST_LOG_TRIVIAL(info) << "Logging started.";

但是我看不到我的信息。但是当我注释掉对set_filter()的调用时,会出现消息。 logOptions.m_severity的值为0,即应允许所有消息。试图在operator()中设置断点并检查发生了什么-它似乎正常工作。 我在做什么错了?

1 个答案:

答案 0 :(得分:1)

问题是您尝试提取的属性值类型不正确。当int使用的记录器使用BOOST_LOG_TRIVIAL时,您将类型明确指定为boost::log::trivial::severity_level。在这种情况下,extract调用的结果是一个空的value_ref实例,该实例将在任何比较运算符上返回false

编写过滤器的一种更好,更正确的方法是使用属性关键字,该关键字要同时注意属性名称及其值类型。由于您使用的是普通日志记录API,因此库已经定义了一个关键字,该关键字与名为“严重性”的属性相对应,该属性的值类型为boost::log::trivial::severity_levelboost::log::trivial::severity

bool operator()(const boost::log::attribute_value_set& attrs) const noexcept
{
    // returns an empty value_ref if the attribute value is not found
    // or has a different type
    auto sev = attrs[boost::log::trivial::severity];
    return !sev || sev >= m_logLevel;
}