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

如何深度复制boost::log::sources::severity_channel_logger_mt对象?需创建带指定通道且继承源日志器所有属性的新实例

如何深度复制boost::log::sources::severity_channel_logger_mt并指定新通道

你遇到的问题很典型:Boost Log 1.66版本里,直接用现有构造方式要么没法继承原日志器的属性,要么修改新日志器的通道会影响原实例。我来给你捋清楚问题根源,再给出可靠的解决方案。

先分析你现有代码的问题

  • 方法一:带通道参数的构造函数

    Logger l0 {orig, keywords::channel = "L0"};
    

    这个构造函数不会修改原日志器,但它的设计逻辑是复用原日志器的核心配置(比如关联的sink、过滤规则),不会自动复制原日志器的自定义属性(比如你添加的tid属性不会被l0继承)。

  • 方法二:拷贝构造后修改通道

    Logger l1 {orig};
    l1.channel("L1");
    

    拷贝构造出来的l1会共享原日志器的属性容器,调用channel()方法修改的是共享的通道属性,所以会意外修改原日志器orig的通道值,这显然不是你想要的。

正确的深度复制方案

要实现「继承所有属性+独立新通道+不影响原日志器」,需要手动复制原日志器的所有属性,并确保新日志器拥有独立的属性集合。具体步骤如下:

  1. 创建一个指定新通道的新日志器实例;
  2. 遍历原日志器的所有属性,逐个克隆并添加到新日志器中(clone()方法会创建属性的独立副本,避免共享);
  3. 按需添加新属性或修改配置,完全不会影响原日志器。

完整代码示例

using namespace boost::log;
using Logger = sources::severity_channel_logger_mt<trivial::severity_level, std::string>;

int main() {
    // 原日志器
    Logger orig {keywords::channel = "LL"};
    orig.add_attribute("tid", attributes::constant<std::string>("TT"));

    // 1. 创建带新通道的新日志器
    Logger cloned_logger {keywords::channel = "NewChannel"};

    // 2. 深度复制原日志器的所有属性
    auto orig_attributes = orig.attribute_values();
    for (const auto& attr_pair : orig_attributes) {
        // 使用clone()创建属性的独立副本,避免与原日志器共享
        cloned_logger.add_attribute(attr_pair.first, attr_pair.second.clone());
    }

    // 3. 测试:修改新日志器的属性和通道,不会影响原日志器
    cloned_logger.add_attribute("attr", attributes::constant<std::string>("0A"));
    cloned_logger.channel("UpdatedNewChannel");

    // 验证原日志器状态未变
    BOOST_LOG(orig) << "原日志器通道:" << orig.channel(); // 输出 "LL"
    BOOST_LOG(orig) << "原日志器tid属性:" << orig.attribute_values()["tid"].extract<std::string>(); // 输出 "TT"

    return 0;
}

封装成工具函数(可选)

如果需要频繁复制日志器,可以封装一个通用函数,方便复用:

template<typename LoggerType>
LoggerType deep_copy_logger_with_channel(const LoggerType& source_logger, 
                                         const typename LoggerType::channel_type& new_channel) {
    // 创建带新通道的日志器
    LoggerType new_logger(boost::log::keywords::channel = new_channel);

    // 复制所有属性
    auto source_attrs = source_logger.attribute_values();
    for (const auto& attr : source_attrs) {
        new_logger.add_attribute(attr.first, attr.second.clone());
    }

    // 可选:复制过滤规则、关联的sink等其他配置
    new_logger.set_filter(source_logger.filter());
    new_logger.add_sinks(source_logger.sinks());

    return new_logger;
}

调用方式非常简单:

Logger cloned_logger = deep_copy_logger_with_channel(orig, "MyNewChannel");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:09:08