Boost Log V2:从配置文件设置日志过滤器

时间:2021-05-20 18:42:17

标签: c++ boost boost-log

我只想设置一个 Boost Log V2 接收器 (Boost 1.75.0) 以从生成应用程序的日志记录中过滤掉几行。 目标是拥有一个仅包含这些行的日志文件(例如:登录的用户),而另一个接收器会注销所有记录

我尝试在配置文件中配置接收器的过滤器属性以匹配标记存在,如下所示:

[Sinks.FileSink]
Destination=TextFile
Filter="%USER%"
FileName="log.log"
MaxSize=10000000
Format="[%TimeStamp%] - %Message%"
Asynchronous=false
AutoFlush=true

其中 %USER% 标记是过滤条件,如果存在,记录该行,否则不...

我尝试添加为 value 属性:

... << boost::log::add_value("USER", true) << "message..."

并在从文件记录器之前注册它:

boost::log::core::get()->add_global_attribute("USER", boost::log::attributes::mutable_constant(true));
boost::log::init_from_stream(config);

它们都不起作用

对我来说,奇怪的行为是,如果我过滤严重性,过滤模式会起作用,如下所示:Filter="%Severity%"

谁能帮助我如何从应用程序中过滤掉很少的行并将它们转发到文件中?

谢谢

更新:

一个想要展示我想要实现的目标的最小示例:

#include <boost/log/utility/setup/from_stream.hpp>
#include <boost/log/attributes/mutable_constant.hpp>

int main(int argc, char *argv_char[]) {
std::stringstream config;
config << R"([Core])" << std::endl;
config << R"(DisableLogging=false)" << std::endl;
config << R"(Filter="%Severity% >= trace")" << std::endl;

config << R"([Sinks.Sink])" << std::endl;
config << R"(Destination=Console)" << std::endl;
//config << R"(Filter="%CMD% = \"YES\"")" << std::endl;
config << R"(Filter="%CMD% = \"NO\"")" << std::endl;
config << R"(FileName="commands.log")" << std::endl;
config << R"(Format="%Message%")" << std::endl;
config << R"(Asynchronous=false)" << std::endl;
config << R"(AutoFlush=true)" << std::endl;

boost::log::core::get()->add_global_attribute("CMD", boost::log::attributes::mutable_constant<std::string>("NO"));
boost::log::init_from_stream(config);

BOOST_LOG_TRIVIAL(debug) << "Non-visible message";
BOOST_LOG_TRIVIAL(debug) << boost::log::add_value("CMD", "YES") << "Visible message";

return 0;
}

如果我将过滤条件替换为 %CMD% = "YES",则输出中缺少所需的日志行

更新 2:

// Codes above didn't changed
boost::log::init_from_stream(config);

boost::log::sources::logger logger;
logger.add_attribute("CMD",   boost::log::attributes::constant<std::string>("YES"));
BOOST_LOG(logger) << "A log message from logger";

boost::log::sources::logger loggerScoped;
BOOST_LOG_SCOPED_LOGGER_ATTR(loggerScoped, "CMD", boost::log::attributes::constant<std::string>("YES"));
BOOST_LOG(loggerScoped) << "A log message from loggerScoped";


BOOST_LOG_TRIVIAL(debug) << "Non-visible message";
BOOST_LOG_TRIVIAL(debug) << boost::log::add_value("CMD", "YES") << "Visible message";

return 0;

1 个答案:

答案 0 :(得分:0)

documentation 中所述,add_value 操纵器对过滤没有影响,因为它是在过滤完成后执行的。在您的代码示例中,您设置了一个值为“NO”的全局字符串属性“CMD”,这就是两个日志记录的过滤器正在测试的内容。当您将过滤器更改为需要值“YES”时,两个日志记录都会被抑制。

如果要选择性地禁用某些日志记录,则应使用其他方式注册该属性,使其在过滤点生效。例如,您可以将属性添加到记录器(通过在记录器上调用 add_attribute)并使用该记录器发出您想要抑制的日志记录。或者您可以使用 scoped attributes 来标记在给定代码区域中发出的日志记录。下面是一个更新的代码示例:

#include <string>
#include <sstream>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/from_stream.hpp>
#include <boost/log/utility/manipulators/add_value.hpp>
#include <boost/log/attributes/mutable_constant.hpp>
#include <boost/log/attributes/scoped_attribute.hpp>
#include <boost/log/sources/logger.hpp>

int main(int argc, char *argv_char[]) {
    std::stringstream config;
    config << R"([Core])" << std::endl;
    config << R"(DisableLogging=false)" << std::endl;
    //config << R"(Filter="%Severity% >= trace")" << std::endl;

    config << R"([Sinks.Sink])" << std::endl;
    config << R"(Destination=Console)" << std::endl;
    config << R"(Filter="%CMD% = \"YES\"")" << std::endl;
    config << R"(Format="%Message%")" << std::endl;
    config << R"(Asynchronous=false)" << std::endl;
    config << R"(AutoFlush=true)" << std::endl;

    boost::log::core::get()->add_global_attribute("CMD", boost::log::attributes::mutable_constant<std::string>("NO"));
    boost::log::init_from_stream(config);

    boost::log::sources::logger logger;
    logger.add_attribute("CMD",   boost::log::attributes::constant<std::string>("YES"));
    BOOST_LOG(logger) << "A log message from logger";

    {
        boost::log::sources::logger loggerScoped;
        BOOST_LOG_SCOPED_LOGGER_ATTR(loggerScoped, "CMD", boost::log::attributes::constant<std::string>("YES"));
        BOOST_LOG(loggerScoped) << "A log message from loggerScoped";
    }


    BOOST_LOG_TRIVIAL(debug) << "Non-visible message";
    BOOST_LOG_TRIVIAL(debug) << boost::log::add_value("CMD", "YES") << "Still non-visible message";

    return 0;
}