为何tracing-subscriber的message字段值过滤规则不生效?
问题原因
message不属于结构化键值字段:tracing里的message是日志的格式化输出文本,不是事件中显式定义的结构化键值对。Directive语法的[{key=value}]匹配规则只对日志事件里的结构化字段生效,message是通过error!/info!等宏的格式化字符串生成的,不会被当作键值字段存储,因此没法用[{message="xxx"}]这类规则匹配内容。rdkafka的
PartitionEOF日志用其他结构化字段存储标识:rdkafka输出PartitionEOF日志时,会把这个错误信息放在特定的结构化字段里(比如error字段),message只是该字段内容的格式化展示。你需要针对实际存储该标识的字段写过滤规则,而非message内容。
解决方案
1. 定位PartitionEOF对应的结构化字段
先开启结构化日志输出,查看PartitionEOF事件的完整字段信息。比如用JSON格式输出日志:
use tracing_subscriber::{fmt, EnvFilter}; fn main() { tracing_subscriber::fmt() .with_env_filter(EnvFilter::new("debug")) .json() .init(); // 你的rdkafka业务代码 }
运行后找到PartitionEOF对应的日志条目,确认它的标识字段(比如可能是error: "PartitionEOF")。
2. 编写目标字段的过滤规则
假设确认字段是error="PartitionEOF",就可以用这个字段来写过滤规则:
let filter = EnvFilter::new("rdkafka=info,{error=\"PartitionEOF\"}=off"); tracing_subscriber::fmt().with_env_filter(filter).init();
3. 匹配message内容的替代方法
如果必须根据message内容过滤,Directive语法做不到,得用自定义过滤逻辑:
use tracing::{event, Level}; use tracing_subscriber::{filter::FilterFn, fmt}; fn main() { let filter = FilterFn::new(|metadata, _| { // 屏蔽所有message包含"PartitionEOF"的日志 !metadata.message().unwrap_or("").contains("PartitionEOF") }); tracing_subscriber::fmt().with_filter(filter).init(); // 测试示例 event!(Level::ERROR, "This is a PartitionEOF error"); }
内容的提问来源于stack exchange,提问作者ESRogs
相关产品推荐
相关产品推荐

