简体   繁体   中英

How do I limit log levels when multiple logging destinations are used with the rust tracing library?

I have the following code that works for my rust application to write logs to stdout and to a rolling json file.

    let appender = tracing_appender::rolling::hourly(app_log_path.clone(), "application.log");
    let (non_blocking, _guard) = tracing_appender::non_blocking(appender);

    let subscriber = tracing_subscriber::registry()
        .with(fmt::Layer::new().with_writer(std::io::stdout).pretty())
        .with(fmt::Layer::new().with_writer(non_blocking).json());

    tracing::subscriber::set_global_default(subscriber).expect("Unable to set a global collector");

This works but logs all logging levels, including verbose trace logging. I want to limit the logs to only info level, but can't figure out how to do that.

From the tracing documentation it says to do:

fmt()
    .with_max_level(Level::DEBUG)
    .init();

However, I can't find any place in the code I have above where I can add a .with_max_level() function call. Every place I've tried to put it gives different trait violations. Eg

 the following trait bounds were not satisfied:
           `tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriter<'_>`
           which is required by `tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriterExt`
           `&tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriter<'_>`
           which is required by `&tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriterExt`
           `&mut tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriter<'_>`
           which is required by `&mut tracing_subscriber::fmt::Layer<_, Pretty, Format<Pretty>, fn() -> std::io::Stdout {std::io::stdout}>: MakeWriterExt`

There is a .with_max_level() method provided by the MakeWriterExt trait. It is to be called on the writer makers, which in your case are stdout and non_blocking .

use tracing_subscriber::fmt::writer::MakeWriterExt;
// or
// tracing_subscriber::prelude::*;

let subscriber = tracing_subscriber::registry()
    .with(fmt::Layer::new().with_writer(std::io::stdout.with_max_level(Level::INFO)).pretty())
    .with(fmt::Layer::new().with_writer(non_blocking.with_max_level(Level::INFO)).json());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM