1
1
//! Wrapper for a `Collect` or `Subscribe` to allow it to be dynamically reloaded.
2
2
//!
3
- //! This module provides a type implementing [`Subscribe`] which wraps another type implementing
4
- //! the [`Subscribe`] trait, allowing the wrapped type to be replaced with another
3
+ //! This module provides a type implementing [`Subscribe`] and [`Filter`]
4
+ //! which wraps another type implementing the corresponding trait. This
5
+ //! allows the wrapped type to be replaced with another
5
6
//! instance of that type at runtime.
6
7
//!
7
- //! This can be used in cases where a subset of `Collect` functionality
8
+ //! This can be used in cases where a subset of `Collect` or `Filter` functionality
8
9
//! should be dynamically reconfigured, such as when filtering directives may
9
10
//! change at runtime. Note that this subscriber introduces a (relatively small)
10
11
//! amount of overhead, and should thus only be used as needed.
11
12
//!
13
+ //! ## Note
14
+ //!
15
+ //! //! The [`Subscribe`] implementation is unable to implement downcasting functionality,
16
+ //! so certain `Subscribers` will fail to reload if wrapped in a `reload::Subscriber`.
17
+ //!
18
+ //! If you only want to be able to dynamically change the
19
+ //! `Filter` on your layer, prefer wrapping that `Filter` in the `reload::Subscriber`.
20
+ //!
12
21
//! [`Subscribe`]: crate::Subscribe
22
+ //! [`Filter`]: crate::subscribe::Filter
13
23
use crate :: subscribe;
14
24
use crate :: sync:: RwLock ;
15
25
@@ -23,7 +33,10 @@ use tracing_core::{
23
33
span, Event , Metadata ,
24
34
} ;
25
35
26
- /// Wraps a `Collect` or `Subscribe`, allowing it to be reloaded dynamically at runtime.
36
+ /// Wraps a `Filter` or `Subscribe`, allowing it to be reloaded dynamically at runtime.
37
+ ///
38
+ /// [`Filter`]: crate::subscribe::Filter
39
+ /// [`Subscribe`]: crate::Subscribe
27
40
#[ derive( Debug ) ]
28
41
pub struct Subscriber < S > {
29
42
// TODO(eliza): this once used a `crossbeam_util::ShardedRwLock`. We may
@@ -119,10 +132,67 @@ where
119
132
}
120
133
}
121
134
122
- impl < S > Subscriber < S > {
123
- /// Wraps the given `Subscribe`, returning a subscriber and a `Handle` that allows
135
+ #[ cfg( all( feature = "registry" , feature = "std" ) ) ]
136
+ #[ cfg_attr( docsrs, doc( cfg( all( feature = "registry" , feature = "std" ) ) ) ) ]
137
+ impl < S , C > crate :: subscribe:: Filter < C > for Subscriber < S >
138
+ where
139
+ S : crate :: subscribe:: Filter < C > + ' static ,
140
+ C : Collect ,
141
+ {
142
+ #[ inline]
143
+ fn callsite_enabled ( & self , metadata : & ' static Metadata < ' static > ) -> Interest {
144
+ try_lock ! ( self . inner. read( ) , else return Interest :: sometimes( ) ) . callsite_enabled ( metadata)
145
+ }
146
+
147
+ #[ inline]
148
+ fn enabled ( & self , metadata : & Metadata < ' _ > , ctx : & subscribe:: Context < ' _ , C > ) -> bool {
149
+ try_lock ! ( self . inner. read( ) , else return false ) . enabled ( metadata, ctx)
150
+ }
151
+
152
+ #[ inline]
153
+ fn on_new_span (
154
+ & self ,
155
+ attrs : & span:: Attributes < ' _ > ,
156
+ id : & span:: Id ,
157
+ ctx : subscribe:: Context < ' _ , C > ,
158
+ ) {
159
+ try_lock ! ( self . inner. read( ) ) . on_new_span ( attrs, id, ctx)
160
+ }
161
+
162
+ #[ inline]
163
+ fn on_record (
164
+ & self ,
165
+ span : & span:: Id ,
166
+ values : & span:: Record < ' _ > ,
167
+ ctx : subscribe:: Context < ' _ , C > ,
168
+ ) {
169
+ try_lock ! ( self . inner. read( ) ) . on_record ( span, values, ctx)
170
+ }
171
+
172
+ #[ inline]
173
+ fn on_enter ( & self , id : & span:: Id , ctx : subscribe:: Context < ' _ , C > ) {
174
+ try_lock ! ( self . inner. read( ) ) . on_enter ( id, ctx)
175
+ }
176
+
177
+ #[ inline]
178
+ fn on_exit ( & self , id : & span:: Id , ctx : subscribe:: Context < ' _ , C > ) {
179
+ try_lock ! ( self . inner. read( ) ) . on_exit ( id, ctx)
180
+ }
181
+
182
+ #[ inline]
183
+ fn on_close ( & self , id : span:: Id , ctx : subscribe:: Context < ' _ , C > ) {
184
+ try_lock ! ( self . inner. read( ) ) . on_close ( id, ctx)
185
+ }
186
+ }
187
+
188
+ impl < T > Subscriber < T > {
189
+ /// Wraps the given `Subscribe` or `Filter`,
190
+ /// returning a subscriber or filter and a `Handle` that allows
124
191
/// the inner type to be modified at runtime.
125
- pub fn new ( inner : S ) -> ( Self , Handle < S > ) {
192
+ ///
193
+ /// [`Filter`]: crate::subscribe::Filter
194
+ /// [`Subscribe`]: crate::Subscribe
195
+ pub fn new ( inner : T ) -> ( Self , Handle < T > ) {
126
196
let this = Self {
127
197
inner : Arc :: new ( RwLock :: new ( inner) ) ,
128
198
} ;
@@ -131,7 +201,7 @@ impl<S> Subscriber<S> {
131
201
}
132
202
133
203
/// Returns a `Handle` that can be used to reload the wrapped `Subscribe`.
134
- pub fn handle ( & self ) -> Handle < S > {
204
+ pub fn handle ( & self ) -> Handle < T > {
135
205
Handle {
136
206
inner : Arc :: downgrade ( & self . inner ) ,
137
207
}
@@ -140,22 +210,25 @@ impl<S> Subscriber<S> {
140
210
141
211
// ===== impl Handle =====
142
212
143
- impl < S > Handle < S > {
144
- /// Replace the current subscriber with the provided `new_subscriber`.
213
+ impl < T > Handle < T > {
214
+ /// Replace the current subscriber or filter with the provided `new_value`.
215
+ ///
216
+ /// [`Handle::reload`] cannot be used with the [`Filtered`](crate::filter::Filtered)
217
+ /// subscriber; use [`Handle::modify`] instead (see [this issue] for additional details).
218
+ ///
219
+ /// However, if the _only_ the [`Filter`](crate::subscribe::Filter) needs to be modified,
220
+ /// use `reload::Subscriber` to wrap the `Filter` directly.
145
221
///
146
- /// **Warning:** The [`Filtered`](crate::filter::Filtered) type currently can't be changed
147
- /// at runtime via the [`Handle::reload`] method.
148
- /// Use the [`Handle::modify`] method to change the filter instead.
149
- /// (see <https://github.com/tokio-rs/tracing/issues/1629>)
150
- pub fn reload ( & self , new_subscriber : impl Into < S > ) -> Result < ( ) , Error > {
151
- self . modify ( |subscriber| {
152
- * subscriber = new_subscriber. into ( ) ;
222
+ /// [this issue]: https://github.com/tokio-rs/tracing/issues/1629
223
+ pub fn reload ( & self , new_value : impl Into < T > ) -> Result < ( ) , Error > {
224
+ self . modify ( |object| {
225
+ * object = new_value. into ( ) ;
153
226
} )
154
227
}
155
228
156
229
/// Invokes a closure with a mutable reference to the current subscriber,
157
230
/// allowing it to be modified in place.
158
- pub fn modify ( & self , f : impl FnOnce ( & mut S ) ) -> Result < ( ) , Error > {
231
+ pub fn modify ( & self , f : impl FnOnce ( & mut T ) ) -> Result < ( ) , Error > {
159
232
let inner = self . inner . upgrade ( ) . ok_or ( Error {
160
233
kind : ErrorKind :: CollectorGone ,
161
234
} ) ?;
@@ -182,16 +255,16 @@ impl<S> Handle<S> {
182
255
183
256
/// Returns a clone of the subscriber's current value if it still exists.
184
257
/// Otherwise, if the collector has been dropped, returns `None`.
185
- pub fn clone_current ( & self ) -> Option < S >
258
+ pub fn clone_current ( & self ) -> Option < T >
186
259
where
187
- S : Clone ,
260
+ T : Clone ,
188
261
{
189
- self . with_current ( S :: clone) . ok ( )
262
+ self . with_current ( T :: clone) . ok ( )
190
263
}
191
264
192
265
/// Invokes a closure with a borrowed reference to the current subscriber,
193
266
/// returning the result (or an error if the collector no longer exists).
194
- pub fn with_current < T > ( & self , f : impl FnOnce ( & S ) -> T ) -> Result < T , Error > {
267
+ pub fn with_current < T2 > ( & self , f : impl FnOnce ( & T ) -> T2 ) -> Result < T2 , Error > {
195
268
let inner = self . inner . upgrade ( ) . ok_or ( Error {
196
269
kind : ErrorKind :: CollectorGone ,
197
270
} ) ?;
@@ -200,7 +273,7 @@ impl<S> Handle<S> {
200
273
}
201
274
}
202
275
203
- impl < S > Clone for Handle < S > {
276
+ impl < T > Clone for Handle < T > {
204
277
fn clone ( & self ) -> Self {
205
278
Handle {
206
279
inner : self . inner . clone ( ) ,
0 commit comments