1#![expect(clippy::unwrap_used, reason = "This file needs a bit more cleanup.")]
2
3use std::{ptr, sync::atomic::Ordering};
4
5use tracing_core::{
6 Event,
7 LevelFilter,
8 Metadata,
9 span,
10 subscriber::{Interest, Subscriber},
11};
12use tracing_subscriber::{layer, registry::LookupSpan};
13
14use crate::{Layer, ReloadRouting, subscriber::ReloadSubscriber};
15
16impl<L, S> tracing_subscriber::Layer<S> for Layer<L, S>
17where
18 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
19 L: tracing_subscriber::Layer<ReloadSubscriber<S>>,
20{
21 fn on_layer(&mut self, subscriber: &mut S) {
22 let mut filters = try_lock!(self.inner.filters.lock());
23 filters.backup = subscriber.register_filter();
24 for _ in 1..crate::MAX_FILTER_COUNT.get() {
25 filters.free.push(subscriber.register_filter());
26 }
27
28 let inner_subscriber = unsafe { std::mem::transmute::<&'_ S, &'static S>(&*subscriber) };
29
30 let mut fake_subscriber = ReloadSubscriber::new(inner_subscriber, filters.clone());
31
32 unsafe {
33 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
34 try_lock!(self.inner.layers.write())
35 .last_mut()
36 .unwrap()
37 .as_mut()
38 .get_unchecked_mut()
39 .on_layer(&mut fake_subscriber);
40 }
41 }
42
43 fn on_register_dispatch(&self, subscriber: &tracing_core::Dispatch) {
44 #[expect(
48 clippy::expect_used,
49 reason = "Panicking here might prevent worse bugs. This should only be called during \
50 startup."
51 )]
52 self.inner
53 .dispatch
54 .set(subscriber.downgrade())
55 .expect("on_register_dispatch should be called only once");
56
57 <L as layer::Layer<ReloadSubscriber<S>>>::on_register_dispatch(
58 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
59 try_lock!(self.inner.layers.read()).last().unwrap(),
60 subscriber,
61 );
62 }
63
64 #[inline]
65 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
66 <L as layer::Layer<ReloadSubscriber<S>>>::register_callsite(
67 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
68 try_lock!(self.inner.layers.read(), else return Interest::sometimes())
69 .last()
70 .unwrap(),
71 metadata,
72 )
73 }
74
75 #[inline]
76 fn enabled(&self, metadata: &Metadata<'_>, _ctx: layer::Context<'_, S>) -> bool {
77 #[expect(
78 clippy::expect_used,
79 reason = "TODO when can this happen and is sentinel return value better than \
80 panicking."
81 )]
82 self.with_ctx(move |ctx| {
83 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
84 try_lock!(self.inner.layers.read(), else return false)
85 .last()
86 .unwrap()
87 .enabled(metadata, ctx)
88 })
89 .expect("could not get value for enabled")
90 }
91
92 #[inline]
93 fn event_enabled(&self, event: &Event<'_>, _ctx: layer::Context<'_, S>) -> bool {
94 #[expect(
95 clippy::expect_used,
96 reason = "TODO when can this happen and is sentinel return value better than \
97 panicking."
98 )]
99 self.with_ctx(move |ctx| {
100 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
101 try_lock!(self.inner.layers.read(), else return false)
102 .last()
103 .unwrap()
104 .event_enabled(event, ctx)
105 })
106 .expect("could not get value for event_enabled")
107 }
108
109 #[inline]
110 fn max_level_hint(&self) -> Option<LevelFilter> {
111 <L as layer::Layer<ReloadSubscriber<S>>>::max_level_hint(
112 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
113 try_lock!(self.inner.layers.read(), else return None)
114 .last()
115 .unwrap(),
116 )
117 }
118
119 #[inline]
120 fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) {
121 let index = {
122 let layers = try_lock!(self.inner.layers.read());
123 let index = match self.span_routing {
124 ReloadRouting::NewSpanToLatestLayer => layers.len() - 1,
125 ReloadRouting::NewSpanToParentLayer => {
126 let parent_id = attrs.parent().cloned().or_else(|| {
127 attrs
128 .is_contextual()
129 .then_some(ctx.current_span().id().cloned())
130 .flatten()
131 });
132 parent_id
133 .and_then(|parent_id| {
134 let span_map = try_lock!(self.inner.span_map.read(), else return None);
135 span_map.get(&parent_id).copied()
136 })
137 .unwrap_or(layers.len() - 1)
138 },
139 };
140 self.with_ctx(move |ctx| {
141 layers.get(index).unwrap().on_new_span(attrs, id, ctx);
142 })
143 .unwrap();
144 index
145 };
146 let mut span_map = try_lock!(self.inner.span_map.write());
147 span_map.insert(id.clone(), index);
148 }
149
150 #[inline]
151 fn on_record(&self, span: &span::Id, values: &span::Record<'_>, _ctx: layer::Context<'_, S>) {
152 self.with_span(span, |layer| {
153 self.with_ctx(move |ctx| layer.on_record(span, values, ctx))
154 });
155 }
156
157 #[inline]
158 fn on_follows_from(&self, span: &span::Id, follows: &span::Id, _ctx: layer::Context<'_, S>) {
159 let idx = {
160 let span_map = try_lock!(self.inner.span_map.read());
161 span_map.get(span).copied()
162 };
163 if let Some(idx) = idx {
164 let current = try_lock!(self.inner.layers.read());
165 if let Some(layer) = current.get(idx) {
166 self.with_ctx(move |ctx| {
167 layer.on_follows_from(span, follows, ctx);
168 });
169 }
170 }
171 }
172
173 #[inline]
174 fn on_event(&self, event: &Event<'_>, ctx: layer::Context<'_, S>) {
175 let span_id = event
176 .parent()
177 .cloned()
178 .or_else(|| ctx.current_span().id().cloned());
179
180 if let Some(span_id) = span_id {
181 self.with_span(&span_id, |layer| {
182 self.with_ctx(move |ctx| layer.on_event(event, ctx))
183 });
184 } else {
185 self.with_ctx(move |ctx| {
186 #[expect(clippy::unwrap_used, reason = "There is always at least one layer.")]
187 try_lock!(self.inner.layers.read())
188 .last()
189 .unwrap()
190 .on_event(event, ctx);
191 });
192 }
193 }
194
195 #[inline]
196 fn on_enter(&self, id: &span::Id, _ctx: layer::Context<'_, S>) {
197 self.with_span(id, |layer| {
198 self.with_ctx(move |ctx| layer.on_enter(id, ctx))
199 });
200 }
201
202 #[inline]
203 fn on_exit(&self, id: &span::Id, _ctx: layer::Context<'_, S>) {
204 self.with_span(id, |layer| self.with_ctx(move |ctx| layer.on_exit(id, ctx)));
205 }
206
207 #[inline]
208 fn on_close(&self, id: span::Id, _ctx: layer::Context<'_, S>) {
209 let index = {
210 let mut span_map = try_lock!(self.inner.span_map.write());
211 span_map.remove(&id).unwrap()
212 };
213 self.with_ctx(move |ctx| {
214 try_lock!(self.inner.layers.read())
215 .get(index)
216 .unwrap()
217 .on_close(id, ctx);
218 });
219 }
220
221 #[inline]
222 fn on_id_change(&self, old: &span::Id, new: &span::Id, _ctx: layer::Context<'_, S>) {
223 let index = {
224 let mut span_map = try_lock!(self.inner.span_map.write());
225 let index = span_map.remove(old).unwrap();
226 span_map.insert(new.clone(), index);
227 index
228 };
229 self.with_ctx(move |ctx| {
230 try_lock!(self.inner.layers.read())
231 .get(index)
232 .unwrap()
233 .on_id_change(old, new, ctx);
234 });
235 }
236
237 #[doc(hidden)]
238 unsafe fn downcast_raw(&self, id: core::any::TypeId) -> Option<*const ()> {
239 if id == core::any::TypeId::of::<Self>() {
240 return Some(ptr::from_ref(self).cast::<()>());
241 }
242
243 if id == core::any::TypeId::of::<ReloadSubscriber<S>>() {
244 let dispatch = self.inner.dispatch.get()?.upgrade()?;
245
246 if !self.inner.dispatch_leaked.swap(true, Ordering::Relaxed) {
248 std::mem::forget(dispatch.clone());
249 }
250
251 let subscriber = dispatch.downcast_ref::<S>()?;
252
253 let static_subscriber = unsafe { std::mem::transmute::<&'_ S, &'static S>(subscriber) };
271
272 return Some(
273 try_lock!(self.subscriber_cache.lock(), else return None)
274 .get(id, static_subscriber),
275 );
276 }
277
278 let current = try_lock!(self.inner.layers.read(), else return None);
279
280 current.last().and_then(|layer| unsafe {
281 <L as layer::Layer<ReloadSubscriber<S>>>::downcast_raw(layer, id)
282 })
283 }
284}