tokio-rs / tracing

Application level tracing for Rust.
https://tracing.rs
MIT License
5.15k stars 673 forks source link

EnvFilters do not work when using `Vec<Box<dyn Layer>>` #2929

Open mdecimus opened 3 months ago

mdecimus commented 3 months ago

Bug Report

Version

% cargo tree | grep tracing
│   │   │   │   │   │   └── tracing v0.1.40
│   │   │   │   │   │       ├── tracing-attributes v0.1.27 (proc-macro)
│   │   │   │   │   │       └── tracing-core v0.1.32
│   │   │   │   └── tracing v0.1.40 (*)
│   │   │   │   │   │   └── tracing v0.1.40 (*)
│   │   │   │   │   │   ├── tracing v0.1.40 (*)
│   │   │   │   │   │   │   │   ├── tracing v0.1.40 (*)
│   │   │   │   │   │   │   └── tracing v0.1.40 (*)
│   │   │   │   │   │   │   └── tracing v0.1.40 (*)
│   │   │   │   │   │   │   │   │   └── tracing v0.1.40 (*)
│   │   │   │   │   │   │   │   └── tracing v0.1.40 (*)
│   │   │   │   │   ├── tracing v0.1.40 (*)
│   │   │   │   │   ├── tracing-journald v0.3.0
│   │   │   │   │   │   ├── tracing-core v0.1.32 (*)
│   │   │   │   │   │   └── tracing-subscriber v0.3.18
│   │   │   │   │   │       ├── tracing v0.1.40 (*)
│   │   │   │   │   │       ├── tracing-core v0.1.32 (*)
│   │   │   │   │   │       └── tracing-log v0.2.0
│   │   │   │   │   │           └── tracing-core v0.1.32 (*)
│   │   │   ├── tracing v0.1.40 (*)
│   │   ├── tracing v0.1.40 (*)
│   ├── tracing v0.1.40 (*)
│   │       └── tracing v0.1.40 (*)
├── tracing v0.1.40 (*)
├── tracing-appender v0.2.3
│   └── tracing-subscriber v0.3.18 (*)
├── tracing-journald v0.3.0 (*)
├── tracing-opentelemetry v0.23.0
│   ├── tracing v0.1.40 (*)
│   ├── tracing-core v0.1.32 (*)
│   ├── tracing-log v0.2.0 (*)
│   └── tracing-subscriber v0.3.18 (*)
├── tracing-subscriber v0.3.18 (*)
│   │   └── tracing v0.1.40 (*)
│   │   ├── tracing v0.1.40 (*)
│   ├── tracing v0.1.40 (*)
├── tracing v0.1.40 (*)
│   ├── tracing v0.1.40 (*)
├── tracing v0.1.40 (*)
├── tracing v0.1.40 (*)
├── tracing-subscriber v0.3.18 (*)

Platform

Darwin local22.6.0 Darwin Kernel Version 22.6.0

Description

I need to dynamically create layers for different logging mechanisms. I found out that EnvFilter does not work (i.e. no logging at all is done) when a Vec<Box<dyn Layer>> is used.

For example,

        let mut layers = Vec::new();
        layers.push(
            tracing_subscriber::fmt::layer()
                .with_ansi(true)
                .and_then(
                    EnvFilter::builder()
                        .parse(format!("crate1=INFO,crate2=DEBUG,crate3=INFO"))
                        .unwrap(),
                )
                .boxed(),
        );
        Registry::default().with(layers).init();

The problem seems related to passing the layer inside a Vec because the following code does produce log events:

        Registry::default()
            .with(
                tracing_subscriber::fmt::layer()
                    .with_ansi(true)
                    .and_then(
                        EnvFilter::builder()
                            .parse(format!("crate1=INFO,crate2=DEBUG,crate3=INFO"))
                            .unwrap(),
                    )
                    .boxed(),
            )
            .init();
mdecimus commented 3 months ago

The following also does not work:

Registry::default().with(EnvFilter::builder().parse(format!("crate1=INFO,crate2=DEBUG,crate3=INFO")).unwrap())
              .with(layers)

Update:

I found a different approach that works:


        let mut layers: Option<Box<dyn Layer<Registry> + Sync + Send>> = None;

 loop {
          let layer = // Create layer;  

            layers = Some(match layers {
                Some(layers) => layers.and_then(new_layer).boxed(),
                None => layer,
            });
 }

       tracing_subscriber::registry().with(layers.expect("no layers found")).init()

I am leaving this open anyway in case the issue described above is a bug with EnvFilters and boxed layers.