Expand description
Wrapper for a Layer to allow it to be dynamically modified
at runtime. This is based on tracing_subscriber::reload.
This crate provides a Layer type implementing the Layer
trait which wraps another type implementing the same trait.
The inner value is pinned on construction so its memory address is stable. Reloads publish a new
value and retire the old one instead of mutating in place, which together with pinning keeps
pointers returned from downcast_raw valid. The one-time on_layer setup hook is forwarded
through a transient mutable reference during construction, before any such pointer is handed
out.
The inner value is reloaded by replacing it through Handle::reload_with (or
Handle::reload); it is never mutated in place. Each reload publishes a new value and retires
the previous one, which is kept alive so that pointers previously handed out by downcast_raw
stay valid and all events in a given span can be routed to the same layer. Retired versions are
reclaimed when the subscriber is dropped.
§Why to use this instead of tracing_subscriber::reload::Layer
This layer is built so that downcast_raw is possible through this layer. The price is
leaked memory (and possibly other resources) on every reload.
That happens because downcast_raw returns a raw pointer and if we return a pointer to the
inner layer, we need to guarantee that the pointer is valid for as long as someone has a
reference to the layer. The method has no safety doc comment in tracing-subscriber and from
other usage it is only clear that it should be valid for as long as the &self argument. But we
can never know when that reference goes out of scope, we can only be sure it is safe to clean up
once this Layer is dropped. Until then we have to keep around all layers we have downcasted
to.
Furthermore, this layer tracks which version of the inner layer created a given span and routes
on_event, on_enter, on_exit, and on_close to that layer even if a newer one is
available. This is because some layers depend on information stored in span extensions which is
added on span creation and may panic when reload happens at a wrong time.
§Examples
use tracing_reload::{Layer, Handle};
use tracing_subscriber::{filter, fmt, prelude::*};
let filter = filter::LevelFilter::WARN;
let (filter, reload_handle) = Layer::new(filter);
tracing_subscriber::registry()
.with(filter)
.with(fmt::Layer::default())
.init();
info!("This will be ignored");
reload_handle.reload(filter::LevelFilter::INFO);
info!("This will be logged");Reloading a Filtered layer:
use tracing_subscriber::{filter, fmt, reload, prelude::*};
let filtered_layer = fmt::Layer::default().with_filter(filter::LevelFilter::WARN);
let (filtered_layer, reload_handle) = reload::Layer::new(filtered_layer);
tracing_subscriber::registry()
.with(filtered_layer)
.init();
info!("This will be ignored");
reload_handle.modify(|layer| *layer.filter_mut() = filter::LevelFilter::INFO);
info!("This will be logged");Structs§
- Error
- Indicates that an error occurred when accessing a reloadable layer.
- Handle
- Allows modifying the state of an associated reloadable layer.
- Layer
- Wraps another type implementing
tracing_subscriber::layer::Layerortracing_subscriber::layer::Filter, allowing it to be modified dynamically at runtime. - Reload
Subscriber - This is a fake subscriber that should not be constructed by user-code.
Enums§
- Reload
Routing - Determines how new spans are routed when layers are reloaded.