You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为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_layerstd_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

火山引擎 最新活动