tracing
tracing copied to clipboard
EnvFilters do not work when using `Vec<Box<dyn Layer>>`
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();
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.