1use crate::layer;
68use crate::sync::RwLock;
69
70use core::any::TypeId;
71use std::{
72 error, fmt,
73 marker::PhantomData,
74 sync::{Arc, Weak},
75};
76use tracing_core::{
77 callsite, span,
78 subscriber::{Interest, Subscriber},
79 Dispatch, Event, LevelFilter, Metadata,
80};
81
82#[derive(Debug)]
84pub struct Layer<L, S> {
85 inner: Arc<RwLock<L>>,
90 _s: PhantomData<fn(S)>,
91}
92
93#[derive(Debug)]
95pub struct Handle<L, S> {
96 inner: Weak<RwLock<L>>,
97 _s: PhantomData<fn(S)>,
98}
99
100#[derive(Debug)]
102pub struct Error {
103 kind: ErrorKind,
104}
105
106#[derive(Debug)]
107enum ErrorKind {
108 SubscriberGone,
109 Poisoned,
110}
111
112impl<L, S> crate::Layer<S> for Layer<L, S>
115where
116 L: crate::Layer<S> + 'static,
117 S: Subscriber,
118{
119 fn on_register_dispatch(&self, subscriber: &Dispatch) {
120 try_lock!(self.inner.read()).on_register_dispatch(subscriber);
121 }
122
123 fn on_layer(&mut self, subscriber: &mut S) {
124 try_lock!(self.inner.write(), else return).on_layer(subscriber);
125 }
126
127 #[inline]
128 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
129 try_lock!(self.inner.read(), else return Interest::sometimes()).register_callsite(metadata)
130 }
131
132 #[inline]
133 fn enabled(&self, metadata: &Metadata<'_>, ctx: layer::Context<'_, S>) -> bool {
134 try_lock!(self.inner.read(), else return false).enabled(metadata, ctx)
135 }
136
137 #[inline]
138 fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) {
139 try_lock!(self.inner.read()).on_new_span(attrs, id, ctx)
140 }
141
142 #[inline]
143 fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: layer::Context<'_, S>) {
144 try_lock!(self.inner.read()).on_record(span, values, ctx)
145 }
146
147 #[inline]
148 fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: layer::Context<'_, S>) {
149 try_lock!(self.inner.read()).on_follows_from(span, follows, ctx)
150 }
151
152 #[inline]
153 fn event_enabled(&self, event: &Event<'_>, ctx: layer::Context<'_, S>) -> bool {
154 try_lock!(self.inner.read(), else return false).event_enabled(event, ctx)
155 }
156
157 #[inline]
158 fn on_event(&self, event: &Event<'_>, ctx: layer::Context<'_, S>) {
159 try_lock!(self.inner.read()).on_event(event, ctx)
160 }
161
162 #[inline]
163 fn on_enter(&self, id: &span::Id, ctx: layer::Context<'_, S>) {
164 try_lock!(self.inner.read()).on_enter(id, ctx)
165 }
166
167 #[inline]
168 fn on_exit(&self, id: &span::Id, ctx: layer::Context<'_, S>) {
169 try_lock!(self.inner.read()).on_exit(id, ctx)
170 }
171
172 #[inline]
173 fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) {
174 try_lock!(self.inner.read()).on_close(id, ctx)
175 }
176
177 #[inline]
178 fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) {
179 try_lock!(self.inner.read()).on_id_change(old, new, ctx)
180 }
181
182 #[inline]
183 fn max_level_hint(&self) -> Option<LevelFilter> {
184 try_lock!(self.inner.read(), else return None).max_level_hint()
185 }
186
187 #[doc(hidden)]
188 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
189 if id == TypeId::of::<layer::NoneLayerMarker>() {
200 return try_lock!(self.inner.read(), else return None).downcast_raw(id);
201 }
202
203 None
204 }
205}
206
207#[cfg(all(feature = "registry", feature = "std"))]
210#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))]
211impl<S, L> crate::layer::Filter<S> for Layer<L, S>
212where
213 L: crate::layer::Filter<S> + 'static,
214 S: Subscriber,
215{
216 #[inline]
217 fn callsite_enabled(&self, metadata: &'static Metadata<'static>) -> Interest {
218 try_lock!(self.inner.read(), else return Interest::sometimes()).callsite_enabled(metadata)
219 }
220
221 #[inline]
222 fn enabled(&self, metadata: &Metadata<'_>, ctx: &layer::Context<'_, S>) -> bool {
223 try_lock!(self.inner.read(), else return false).enabled(metadata, ctx)
224 }
225
226 #[inline]
227 fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) {
228 try_lock!(self.inner.read()).on_new_span(attrs, id, ctx)
229 }
230
231 #[inline]
232 fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: layer::Context<'_, S>) {
233 try_lock!(self.inner.read()).on_record(span, values, ctx)
234 }
235
236 #[inline]
237 fn on_enter(&self, id: &span::Id, ctx: layer::Context<'_, S>) {
238 try_lock!(self.inner.read()).on_enter(id, ctx)
239 }
240
241 #[inline]
242 fn on_exit(&self, id: &span::Id, ctx: layer::Context<'_, S>) {
243 try_lock!(self.inner.read()).on_exit(id, ctx)
244 }
245
246 #[inline]
247 fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) {
248 try_lock!(self.inner.read()).on_close(id, ctx)
249 }
250
251 #[inline]
252 fn max_level_hint(&self) -> Option<LevelFilter> {
253 try_lock!(self.inner.read(), else return None).max_level_hint()
254 }
255}
256
257impl<L, S> Layer<L, S> {
258 pub fn new(inner: L) -> (Self, Handle<L, S>) {
264 let this = Self {
265 inner: Arc::new(RwLock::new(inner)),
266 _s: PhantomData,
267 };
268 let handle = this.handle();
269 (this, handle)
270 }
271
272 pub fn handle(&self) -> Handle<L, S> {
277 Handle {
278 inner: Arc::downgrade(&self.inner),
279 _s: PhantomData,
280 }
281 }
282}
283
284impl<L, S> Handle<L, S> {
287 pub fn reload(&self, new_value: impl Into<L>) -> Result<(), Error> {
301 self.modify(|layer| {
302 *layer = new_value.into();
303 })
304 }
305
306 pub fn modify(&self, f: impl FnOnce(&mut L)) -> Result<(), Error> {
309 let inner = self.inner.upgrade().ok_or(Error {
310 kind: ErrorKind::SubscriberGone,
311 })?;
312
313 let mut lock = try_lock!(inner.write(), else return Err(Error::poisoned()));
314 f(&mut *lock);
315 drop(lock);
318
319 callsite::rebuild_interest_cache();
320 Ok(())
321 }
322
323 pub fn clone_current(&self) -> Option<L>
326 where
327 L: Clone,
328 {
329 self.with_current(L::clone).ok()
330 }
331
332 pub fn with_current<T>(&self, f: impl FnOnce(&L) -> T) -> Result<T, Error> {
335 let inner = self.inner.upgrade().ok_or(Error {
336 kind: ErrorKind::SubscriberGone,
337 })?;
338 let inner = try_lock!(inner.read(), else return Err(Error::poisoned()));
339 Ok(f(&*inner))
340 }
341}
342
343impl<L, S> Clone for Handle<L, S> {
344 fn clone(&self) -> Self {
345 Handle {
346 inner: self.inner.clone(),
347 _s: PhantomData,
348 }
349 }
350}
351
352impl Error {
355 fn poisoned() -> Self {
356 Self {
357 kind: ErrorKind::Poisoned,
358 }
359 }
360
361 pub fn is_poisoned(&self) -> bool {
364 matches!(self.kind, ErrorKind::Poisoned)
365 }
366
367 pub fn is_dropped(&self) -> bool {
370 matches!(self.kind, ErrorKind::SubscriberGone)
371 }
372}
373
374impl fmt::Display for Error {
375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376 let msg = match self.kind {
377 ErrorKind::SubscriberGone => "subscriber no longer exists",
378 ErrorKind::Poisoned => "lock poisoned",
379 };
380 f.pad(msg)
381 }
382}
383
384impl error::Error for Error {}