Search code examples
rustrust-tokiorust-tracing

Tracing, how to filter logs under specified levels for `Layer`?


Consider the following code, I am writing the log into both standard output and a file. This is approached by Layer, while I don't know how to filter based on level.

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);

    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();

    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();

    tracing_subscriber::registry()
        .with(file_layer)
        .with(std_layer)
        .init();

    guard
}

How can I avoid Level Trace appear in my log? that is, I want only Info, Error, etc. What if I want different filter level for each layer


Solution

  • The way to do it is by using a filter, either in a layer or for all in the registry.

    Therefore, define your filter, like with env filter:

    let the_env_filter = tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
            "your_app=debug,tower_http=debug,axum::rejection=trace".into()
    });
    

    Then, use it either:

    • per layer:

      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(the_env_filter);
      
    • or at registry (for all layers):

      tracing_subscriber::registry()
          .with(file_layer)
          .with(std_layer)
          .with(the_env_filter)
          .init();
      

    More info on the official docs:

    I hope this helps!