tracing_reload/
subscriber.rs1use std::{
8 any::TypeId,
9 ptr,
10 sync::atomic::{AtomicBool, Ordering},
11};
12
13use tracing::{Subscriber, span};
14use tracing_subscriber::registry::LookupSpan;
15
16use crate::ReloadableFilters;
17
18pub struct ReloadSubscriber<S>
24where
25 S: 'static,
26{
27 inner: &'static S,
28 filters: ReloadableFilters,
29 follows_from_called: AtomicBool,
30}
31
32impl<S: 'static> ReloadSubscriber<S> {
33 pub(crate) fn new(inner: &'static S, filters: ReloadableFilters) -> Self {
34 Self {
35 inner,
36 filters,
37 follows_from_called: AtomicBool::new(false),
38 }
39 }
40
41 pub(crate) fn into_filters(self) -> ReloadableFilters {
42 self.filters
43 }
44}
45
46impl<S: Subscriber + 'static> Subscriber for ReloadSubscriber<S> {
47 fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
48 if self.follows_from_called.swap(true, Ordering::Relaxed) {
51 self.inner.record_follows_from(span, follows);
52 }
53 }
54
55 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
56 if id == TypeId::of::<Self>() {
57 Some(ptr::from_ref(self).cast::<()>())
58 } else {
59 unsafe { self.inner.downcast_raw(id) }
60 }
61 }
62
63 fn enabled(&self, metadata: &tracing::Metadata<'_>) -> bool {
66 self.inner.enabled(metadata)
67 }
68
69 fn new_span(&self, span: &span::Attributes<'_>) -> tracing_core::span::Id {
70 self.inner.new_span(span)
71 }
72
73 fn record(&self, span: &span::Id, values: &tracing_core::span::Record<'_>) {
74 self.inner.record(span, values);
75 }
76
77 fn event(&self, event: &tracing::Event<'_>) {
78 self.inner.event(event);
79 }
80
81 fn enter(&self, span: &span::Id) {
82 self.inner.enter(span);
83 }
84
85 fn exit(&self, span: &span::Id) {
86 self.inner.exit(span);
87 }
88
89 fn on_register_dispatch(&self, subscriber: &tracing::Dispatch) {
90 self.inner.on_register_dispatch(subscriber);
91 }
92
93 fn register_callsite(
94 &self,
95 metadata: &'static tracing::Metadata<'static>,
96 ) -> tracing_core::Interest {
97 self.inner.register_callsite(metadata)
98 }
99
100 fn max_level_hint(&self) -> Option<tracing_core::LevelFilter> {
101 self.inner.max_level_hint()
102 }
103
104 fn event_enabled(&self, event: &tracing::Event<'_>) -> bool {
105 self.inner.event_enabled(event)
106 }
107
108 fn clone_span(&self, id: &tracing_core::span::Id) -> tracing_core::span::Id {
109 self.inner.clone_span(id)
110 }
111
112 fn drop_span(&self, id: tracing_core::span::Id) {
113 #[expect(deprecated, reason = "It's deprecated...")]
114 self.inner.drop_span(id);
115 }
116
117 fn try_close(&self, id: tracing_core::span::Id) -> bool {
118 self.inner.try_close(id)
119 }
120
121 fn current_span(&self) -> tracing_core::span::Current {
122 self.inner.current_span()
123 }
124}
125
126impl<'lookup, S: LookupSpan<'lookup>> LookupSpan<'lookup> for ReloadSubscriber<S> {
127 type Data = S::Data;
128
129 fn span_data(&'lookup self, id: &tracing::span::Id) -> Option<Self::Data> {
130 self.inner.span_data(id)
131 }
132
133 fn register_filter(&mut self) -> tracing_subscriber::filter::FilterId {
134 let filters = &mut self.filters;
135
136 let Some(filter_id) = filters.free.pop() else {
137 return filters.backup;
142 };
143
144 filters.used.push(filter_id);
145 filter_id
146 }
147}