How to add a layer to tracing_subscriber's Registry based on a condition?

266 views Asked by At

I need to add a layer to the registry in the below code based on a condition.

As you can see I'm trying two ways: both of them fail.

What can I use?

REPL: https://www.rustexplorer.com/b/n16o51

use tracing_subscriber::{fmt::Layer, prelude::*, EnvFilter, Registry};

#[tokio::main]
async fn main() {
    let mut registry = Registry::default()
        .with(EnvFilter::from("INFO"))
        .with(Layer::default().json().boxed());

    // This doesn't work because of: use of moved value: `registry`
    // if (1 == 1) {
    //     registry.with(Layer::default().pretty().with_file(false).boxed());
    // }

    // This doesn't work because of very strange `mismatched types`
    // if (2 == 2) {
    //     registry = registry.with(Layer::default().pretty().with_file(false).boxed());
    // }

    tracing::subscriber::set_global_default(registry).unwrap();
}
1

There are 1 answers

0
Chayim Friedman On BEST ANSWER

Option<Layer> implements Layer, so the correct way is to use Option:

let registry = Registry::default()
    .with(EnvFilter::from("INFO"))
    .with(Layer::default().json())
    .with(if 2 == 2 {
        Some(Layer::default().pretty().with_file(false))
    } else {
        None
    });

Or:

let registry = Registry::default()
    .with(EnvFilter::from("INFO"))
    .with(Layer::default().json())
    .with((2 == 2).then(|| Layer::default().pretty().with_file(false)));

The assignment doesn't work because each with() wraps the type with Layered, creating a different type.