tokio-rs / tracing

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

subscriber: impl Clone for EnvFilter #2956

Open Benjamin-L opened 2 months ago

Benjamin-L commented 2 months ago

Motivation

In #2360, people have requested impl Clone for EnvFilter in order to use EnvFilter as a clap argument. In conduwuit, we want this in order to do something like this:

let filter_layer: EnvFilter = ...;
let subscriber = Registry::default()
    .with(console_subscriber::spawn())
    .with(logging_subscriber_a.with_filter(filter_layer.clone()))
    .with(logging_subscriber_b.with_filter(filter_layer.clone()))

tokio-console's console_subscriber layer needs to be unfiltered in order to pick up tokio trace events, but we have several "logging-type" layers that we want to apply the configured EnvFilter to.

We considered the workaround of constructing several fresh EnvFilters with EnvFilter::try_new(config.log.clone()), but would prefer to just clone the EnvFilter itself and not have to deal with repeating the parsing/error handling.

Solution

We generally expect users to be cloning an EnvFilter before attaching it to a subscriber, rather than cloning EnvFilters that are already attached. Because of this, we reset all the accumulated dynamic state when cloning. This means that some spans and callsites might be missed when an already-attached EnvFilter is cloned, but the presence of the dynamic state mean that detaching and attaching EnvFilters to existing subscribers (e.g. with reload) already doesn't work very well. This isn't a new class of problem.

There was a previous implementation of this in #2398, that shared the dynamic state between all cloned filters behind an Arc. I chose not do go for that approach because it causes inconsistencies if the cloned filters are attached to different subscribers.

A third option would be to clone the dynamic state, but this gets kinda messy with lock poisoning. I can't think of a scenario where that behavior would actually be better.