You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在boost::log单个Sink上配置多个过滤器?

问题描述

我在使用Boost Log的Sink记录日志时,希望为每个自定义Tag设置不同的日志级别。原本尝试单独为每个Tag设置过滤器:

sink->set_filter(logging::trivial::severity >= logging::trivial::warning && expr::attr<std::string>("Tag") == tag);
[...]
sink->set_filter(logging::trivial::severity >= logging::trivial::warning && expr::attr<std::string>("Tag") == tag1); 

但每次调用set_filter都会覆盖之前的配置,导致只有最后一个Tag的过滤规则生效。当前遍历JSON配置树时,每处理一个叶子节点就直接覆盖Sink的过滤器,代码如下:

void setSinks()
{
    logging::core::get()->add_global_attribute("Tag", attrs::mutable_constant<std::string>(""));

    std::string path = "..../log_config.json";
    
    [def of sink...]
    
    pt::ptree root;
    pt::read_json(path, root);

    std::function<void(pt::ptree, std::string)> parse_tree;

        auto setFilter = [](std::string tag, std::string logLevel) {
        logging::trivial::severity_level level;
        if (logLevel == "TRACE") level = logging::trivial::trace;
        else if (logLevel == "DEBUG") level = logging::trivial::debug;
        else if (logLevel == "INFO") level = logging::trivial::info;
        else if (logLevel == "WARNING") level = logging::trivial::warning;
        else if (logLevel == "ERROR") level = logging::trivial::error;
        else if (logLevel == "FATAL") level = logging::trivial::fatal;
        else level = logging::trivial::debug;

        return logging::trivial::severity >= level && expr::attr<std::string>("Tag") == tag;

    };

    parse_tree = [&sink, &setFilter, &parse_tree](pt::ptree tree, std::string tag)
    {
        for (const auto& v : tree)
        {
            std::string name = v.first;
            pt::ptree value = v.second;
            if (value.empty())
            {
                sink->set_filter(setFilter(tag + "." + name, value.data()));
            }
            else
            {
                parse_tree(value, (tag.empty() ? name : tag + "." + name));
            }
        }
    };

    parse_tree(root, "");
}

需要实现单个Sink上的多Tag过滤规则叠加。

解决思路

问题核心是每次调用set_filter会替换Sink的现有过滤器,而非叠加。正确的做法是将所有Tag的过滤条件用逻辑或(||)组合成一个复合表达式,最后一次性设置给Sink。

修改后的代码
void setSinks()
{
    logging::core::get()->add_global_attribute("Tag", attrs::mutable_constant<std::string>(""));

    std::string path = "..../log_config.json";
    
    [def of sink...]
    
    pt::ptree root;
    pt::read_json(path, root);

    // 初始化复合过滤器为"永远不匹配"的表达式
    auto combined_filter = expr::false_expr();

    auto setFilter = [](std::string tag, std::string logLevel) {
        logging::trivial::severity_level level;
        if (logLevel == "TRACE") level = logging::trivial::trace;
        else if (logLevel == "DEBUG") level = logging::trivial::debug;
        else if (logLevel == "INFO") level = logging::trivial::info;
        else if (logLevel == "WARNING") level = logging::trivial::warning;
        else if (logLevel == "ERROR") level = logging::trivial::error;
        else if (logLevel == "FATAL") level = logging::trivial::fatal;
        else level = logging::trivial::debug;

        return logging::trivial::severity >= level && expr::attr<std::string>("Tag") == tag;
    };

    std::function<void(pt::ptree, std::string)> parse_tree;
    parse_tree = [&combined_filter, &setFilter, &parse_tree](pt::ptree tree, std::string tag)
    {
        for (const auto& v : tree)
        {
            std::string name = v.first;
            pt::ptree value = v.second;
            if (value.empty())
            {
                // 将当前Tag的过滤条件与复合过滤器做逻辑或
                combined_filter = combined_filter || setFilter(tag + "." + name, value.data());
            }
            else
            {
                parse_tree(value, (tag.empty() ? name : tag + "." + name));
            }
        }
    };

    parse_tree(root, "");

    // 最后一次性设置复合过滤器到Sink
    sink->set_filter(combined_filter);
}
关键说明
  • 初始化combined_filter为expr::false_expr(),确保初始状态下没有日志会被匹配,后续逐步叠加规则。
  • 遍历每个配置项时,用||将当前Tag的过滤条件合并到combined_filter中,实现"满足任意一个Tag的规则即允许日志通过"的逻辑。
  • 所有规则合并完成后,再调用一次set_filter将复合表达式设置给Sink,避免每次覆盖。

内容的提问来源于stack exchange,提问作者Forague

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:30:47