可采用装饰器模式对异步日志系统进行非侵入式功能增强,包括日志采样、上下文注入、格式加密、性能计时和多级条件路由五种扩展方案。

如果您希望在C++项目中为异步日志系统动态叠加功能(如日志采样、上下文注入、格式加密、性能计时等),而不修改原有日志器核心逻辑,则可采用装饰器模式对日志中间件进行非侵入式增强。以下是实现该功能增强的多种扩展方案:
一、日志采样装饰器
该装饰器通过概率或阈值控制实际写入日志的请求比例,降低高吞吐场景下的I/O压力,同时保持日志语义完整性。其本质是在调用下游日志器前插入采样判定逻辑。
1、定义抽象日志器接口 std::shared_ptr<Logger>,包含 log(const LogEntry&) 方法;
2、声明 SamplingDecorator 类,继承自 Logger,持有一个 std::shared_ptr<Logger> 成员变量 target_;
立即学习“C++免费学习笔记(深入)”;
3、在 SamplingDecorator::log() 中,生成 [0.0, 1.0) 区间随机浮点数,若小于预设采样率 sample_rate_,则调用 target_->log(entry);
4、将原始 AsyncFileLogger 实例传入 SamplingDecorator 构造函数,构建链式调用节点。
二、上下文注入装饰器
该装饰器自动将当前线程ID、协程ID、请求TraceID、用户身份标识等运行时上下文字段注入到 LogEntry 的 metadata 字段中,避免业务代码重复填充。
1、定义 ContextInjectorDecorator 类,继承 Logger,持有 std::function<std::map<std::string, std::string>()> context_provider_;
2、重写 log() 方法:先调用 context_provider_() 获取上下文映射,再遍历插入 entry.metadata;
3、使用 thread_local static std::string current_trace_id 存储跨异步阶段传递的追踪ID;
4、构造时传入 Lambda 表达式捕获当前 TLS 变量与协程调度器状态,确保每次日志调用获取最新上下文。
三、日志加密装饰器
该装饰器对 LogEntry 中的 message 字段或敏感字段(如 user_email、token)执行AES-128-GCM加密,满足合规性要求,且不改变日志流转路径。
1、引入 OpenSSL 或 libsodium 库,封装 Encryptor 类提供 encrypt(const std::string&) -> std::string 接口;
4、在 EncryptedDecorator::log() 中,深拷贝 entry,调用 encryptor_->encrypt(entry.message) 替换原文本;
3、若 entry.metadata 存在标记键 "sensitive_fields",则对其指定键列表执行逐字段加密;
5、加密密钥通过环境变量读取并经 KMS密钥解封后加载至内存,生命周期与装饰器实例一致。
四、执行耗时计时装饰器
该装饰器自动记录每条日志从 log() 调用到被异步写入器真正消费之间的时间延迟,用于监控日志系统背压状况。
1、定义 TimingDecorator 类,内部维护 std::shared_ptr<Histogram> latency_histogram_;
2、log() 方法起始处调用 auto start = std::chrono::steady_clock::now();
3、调用 target_->log(entry) 后立即获取 end 时间戳,计算 duration_cast<std::chrono::microseconds>(end - start).count();
4、将延迟微秒值提交至 latency_histogram_ 进行分桶统计;
5、该装饰器必须置于装饰链末端附近,以确保测量覆盖完整异步排队+序列化+IO等待过程。
五、多级条件路由装饰器
该装饰器依据日志等级、模块名、关键词匹配等复合条件,将日志条目分发至不同下游目标(如 ERROR 到 Sentry、DEBUG 到本地文件、含 "payment" 的到 Kafka Topic)。
1、定义 RoutingDecorator 类,持有一个 std::vector<std::pair<std::function<bool(const LogEntry&)>, std::shared_ptr<Logger>>> rules_;
2、每个规则由谓词函数和对应日志器组成,谓词返回 true 即触发转发;
3、log() 方法中遍历 rules_,对每个谓词执行 entry 匹配,匹配成功即异步投递副本(非移动),允许多路并行输出;
4、预置默认规则兜底,确保未匹配日志仍流向原始 target_。


















