1
1
//! Wrapper for a `Layer` to allow it to be dynamically reloaded.
2
2
//!
3
3
//! This module provides a [`Layer` type] which wraps another type implementing
4
- //! the [`Layer` trait], allowing the wrapped type to be replaced with another
5
- //! instance of that type at runtime.
4
+ //! the [`Layer`][layer- trait] or [`Filter`] traits , allowing the wrapped type
5
+ //! to be replaced with another instance of that type at runtime.
6
6
//!
7
7
//! This can be used in cases where a subset of `Subscriber` functionality
8
8
//! should be dynamically reconfigured, such as when filtering directives may
52
52
//! info!("This will be logged");
53
53
//! ```
54
54
//!
55
+ //! ## Note
56
+ //!
57
+ //! The [`Layer`][layer-trait] implementation is unable to implement downcasting functionality,
58
+ //! so certain `Layer`s will fail to reload if wrapped in a `reload::Layer`.
59
+ //!
60
+ //! If you only want to be able to dynamically change the
61
+ //! [`Filter`] on your layer, prefer wrapping that [`Filter`] in the `reload::Layer`.
62
+ //!
55
63
//! [`Layer` type]: Layer
56
- //! [`Layer` trait]: super::layer::Layer
64
+ //! [layer-trait]: super::layer::Layer
65
+ //! [`Filter`]: super::layer::Filter
57
66
use crate :: layer;
58
67
use crate :: sync:: RwLock ;
59
68
@@ -68,7 +77,11 @@ use tracing_core::{
68
77
Event , Metadata ,
69
78
} ;
70
79
71
- /// Wraps a `Layer`, allowing it to be reloaded dynamically at runtime.
80
+ /// Wraps a [`Layer`] or [`Filter`], allowing it to be reloaded dynamically at
81
+ /// runtime.
82
+ ///
83
+ /// [`Filter`]: crate::layer::Filter
84
+ /// [`Layer`]: crate::Layer
72
85
#[ derive( Debug ) ]
73
86
pub struct Layer < L , S > {
74
87
// TODO(eliza): this once used a `crossbeam_util::ShardedRwLock`. We may
@@ -160,13 +173,56 @@ where
160
173
}
161
174
}
162
175
163
- impl < L , S > Layer < L , S >
176
+ #[ cfg( all( feature = "registry" , feature = "std" ) ) ]
177
+ #[ cfg_attr( docsrs, doc( cfg( all( feature = "registry" , feature = "std" ) ) ) ) ]
178
+ impl < F , S > crate :: layer:: Filter < S > for Layer < F , S >
164
179
where
165
- L : crate :: Layer < S > + ' static ,
180
+ F : crate :: layer :: Filter < S > + ' static ,
166
181
S : Subscriber ,
167
182
{
168
- /// Wraps the given `Layer`, returning a `Layer` and a `Handle` that allows
183
+ #[ inline]
184
+ fn callsite_enabled ( & self , metadata : & ' static Metadata < ' static > ) -> Interest {
185
+ try_lock ! ( self . inner. read( ) , else return Interest :: sometimes( ) ) . callsite_enabled ( metadata)
186
+ }
187
+
188
+ #[ inline]
189
+ fn enabled ( & self , metadata : & Metadata < ' _ > , ctx : & layer:: Context < ' _ , S > ) -> bool {
190
+ try_lock ! ( self . inner. read( ) , else return false ) . enabled ( metadata, ctx)
191
+ }
192
+
193
+ #[ inline]
194
+ fn on_new_span ( & self , attrs : & span:: Attributes < ' _ > , id : & span:: Id , ctx : layer:: Context < ' _ , S > ) {
195
+ try_lock ! ( self . inner. read( ) ) . on_new_span ( attrs, id, ctx)
196
+ }
197
+
198
+ #[ inline]
199
+ fn on_record ( & self , span : & span:: Id , values : & span:: Record < ' _ > , ctx : layer:: Context < ' _ , S > ) {
200
+ try_lock ! ( self . inner. read( ) ) . on_record ( span, values, ctx)
201
+ }
202
+
203
+ #[ inline]
204
+ fn on_enter ( & self , id : & span:: Id , ctx : layer:: Context < ' _ , S > ) {
205
+ try_lock ! ( self . inner. read( ) ) . on_enter ( id, ctx)
206
+ }
207
+
208
+ #[ inline]
209
+ fn on_exit ( & self , id : & span:: Id , ctx : layer:: Context < ' _ , S > ) {
210
+ try_lock ! ( self . inner. read( ) ) . on_exit ( id, ctx)
211
+ }
212
+
213
+ #[ inline]
214
+ fn on_close ( & self , id : span:: Id , ctx : layer:: Context < ' _ , S > ) {
215
+ try_lock ! ( self . inner. read( ) ) . on_close ( id, ctx)
216
+ }
217
+ }
218
+
219
+ impl < L , S > Layer < L , S > {
220
+ /// Wraps the given `Subscribe` or `Filter`,
221
+ /// returning a subscriber or filter and a `Handle` that allows
169
222
/// the inner type to be modified at runtime.
223
+ ///
224
+ /// [`Filter`]: crate::subscribe::Filter
225
+ /// [`Subscribe`]: crate::Subscribe
170
226
pub fn new ( inner : L ) -> ( Self , Handle < L , S > ) {
171
227
let this = Self {
172
228
inner : Arc :: new ( RwLock :: new ( inner) ) ,
@@ -187,20 +243,21 @@ where
187
243
188
244
// ===== impl Handle =====
189
245
190
- impl < L , S > Handle < L , S >
191
- where
192
- L : crate :: Layer < S > + ' static ,
193
- S : Subscriber ,
194
- {
195
- /// Replace the current layer with the provided `new_layer`.
246
+ impl < L , S > Handle < L , S > {
247
+ /// Replace the current subscriber or filter with the provided `new_value`.
248
+ ///
249
+ /// [`Handle::reload`] cannot be used with the [`Filtered`] `Layer`; use
250
+ /// [`Handle::modify`] instead (see [this issue] for additional details).
251
+ ///
252
+ /// However, if the _only_ the [`Filter`] needs to be modified,
253
+ /// use `reload::Layer` to wrap the `Filter` directly.
196
254
///
197
- /// **Warning:** The [`Filtered`](crate::filter::Filtered) type currently can't be changed
198
- /// at runtime via the [`Handle::reload`] method.
199
- /// Use the [`Handle::modify`] method to change the filter instead.
200
- /// (see <https://github.com/tokio-rs/tracing/issues/1629>)
201
- pub fn reload ( & self , new_layer : impl Into < L > ) -> Result < ( ) , Error > {
202
- self . modify ( |layer| {
203
- * layer = new_layer. into ( ) ;
255
+ /// [`Filtered`]: crate::filter::Filtered
256
+ /// [`Filter`]: crate::layer::Filter
257
+ /// [this issue]: https://github.com/tokio-rs/tracing/issues/1629
258
+ pub fn reload ( & self , new_value : impl Into < L > ) -> Result < ( ) , Error > {
259
+ self . modify ( |object| {
260
+ * object = new_value. into ( ) ;
204
261
} )
205
262
}
206
263
0 commit comments