Skip to content

Commit f71cebe

Browse files
authored
subscriber: impl Clone for EnvFilter (#3360)
This is useful when using `EnvFilter` for multiple identical per-layer filters, as well as with clap and similar libraries that have `Clone` bounds. 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 `EnvFilter`s 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. Fixes: #2360
1 parent 3a1f571 commit f71cebe

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

tracing-subscriber/src/filter/env/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,24 @@ pub struct EnvFilter {
204204
regex: bool,
205205
}
206206

207+
/// Creates an [`EnvFilter`] with the same directives as `self`.
208+
///
209+
/// This does *not* clone any of the dynamic state that [`EnvFilter`] acquires while attached to a
210+
/// subscriber.
211+
impl Clone for EnvFilter {
212+
fn clone(&self) -> EnvFilter {
213+
EnvFilter {
214+
statics: self.statics.clone(),
215+
dynamics: self.dynamics.clone(),
216+
has_dynamics: self.has_dynamics,
217+
by_id: RwLock::default(),
218+
by_cs: RwLock::default(),
219+
scope: ThreadLocal::new(),
220+
regex: self.regex,
221+
}
222+
}
223+
}
224+
207225
type FieldMap<T> = HashMap<Field, T>;
208226

209227
/// Indicates that an error occurred while parsing a `EnvFilter` from an

tracing-subscriber/src/sync.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,12 @@ mod parking_lot_impl {
5454
Ok(self.inner.write())
5555
}
5656
}
57+
58+
impl<T: Default> Default for RwLock<T> {
59+
fn default() -> Self {
60+
RwLock {
61+
inner: parking_lot::RwLock::default(),
62+
}
63+
}
64+
}
5765
}

0 commit comments

Comments
 (0)