如何为tracing的Layer配置日志级别过滤(支持不同Layer设置不同级别)
如何为tracing的Layer配置日志级别过滤(支持不同Layer设置不同级别)
看起来你已经用tracing搭好了同时输出到文件和标准输出的日志结构,现在想要过滤掉Trace级别日志、甚至给不同Layer设置不同的过滤规则对吧?我来一步步帮你搞定这个问题~
核心思路:用LevelFilter给Layer添加级别过滤
tracing的每个Layer都可以通过with_filter方法绑定日志级别过滤规则,我们需要用到tracing_subscriber::filter模块下的LevelFilter枚举,它定义了从TRACE到ERROR的各个级别,设置后会保留该级别及以上的日志。
场景1:全局统一过滤(所有Layer都去掉Trace级别)
如果你希望文件和标准输出都只输出Info、Warn、Error级别的日志(也就是过滤掉Trace和Debug),可以给每个Layer单独添加过滤,方式非常直观:
首先需要导入必要的模块:
use tracing_subscriber::filter::LevelFilter;
然后修改你的Layer定义,给file_layer和std_layer都加上with_filter(LevelFilter::INFO):
pub fn trace() -> tracing_appender::non_blocking::WorkerGuard { let mut log_dir = std::env::current_exe().expect("failed to read cur exe"); log_dir.pop(); log_dir.push("server_log"); let file_appender = tracing_appender::rolling::daily(log_dir, "chat"); let (non_blocking, guard) = tracing_appender::non_blocking(file_appender); let time_offset = offset!(+9); let time_description = format_description!("[year]/[month]/[day]-[hour]:[minute]:[second]"); let timer = OffsetTime::new(time_offset, time_description); // 文件层:设置为INFO及以上级别,过滤Trace和Debug let file_layer = fmt::layer() .with_timer(timer.clone()) .with_line_number(true) .with_thread_ids(true) .with_span_events(FmtSpan::ACTIVE) .with_file(true) .with_writer(non_blocking) .with_ansi(false) .compact() .with_filter(LevelFilter::INFO); // 新增过滤规则 // 标准输出层:同样设置为INFO及以上级别 let std_layer = fmt::layer() .with_timer(timer) .with_line_number(true) .with_thread_ids(true) .with_file(true) .with_span_events(FmtSpan::ACTIVE) .compact() .with_filter(LevelFilter::INFO); // 新增过滤规则 tracing_subscriber::registry() .with(file_layer) .with(std_layer) .init(); guard }
这样修改后,所有Trace级别的日志都会被两个Layer过滤掉,只有Info及以上的日志会输出。
场景2:不同Layer设置不同级别
如果你想让文件层保留更详细的日志(比如Debug及以上),而标准输出只显示Info及以上的关键日志,只需要给两个Layer设置不同的LevelFilter即可:
// 文件层:保留Debug及以上(包含Trace以外的所有级别) let file_layer = fmt::layer() // ... 其他配置不变 .with_filter(LevelFilter::DEBUG); // 标准输出层:只保留Info及以上 let std_layer = fmt::layer() // ... 其他配置不变 .with_filter(LevelFilter::INFO);
这样文件里会记录Debug、Info、Warn、Error的日志,方便排查问题;而控制台只会显示Info及以上的关键日志,避免输出过多干扰开发。
补充说明
LevelFilter的可选值从低到高分别是:
LevelFilter::TRACE:最详细,包含所有级别LevelFilter::DEBUG:调试信息LevelFilter::INFO:普通运行信息LevelFilter::WARN:警告提示LevelFilter::ERROR:错误信息
你可以根据自己的开发或生产需求,灵活选择对应的级别。
备注:内容来源于stack exchange,提问作者realzhujunhao




