Trait bevy::log::tracing_subscriber::Layer

pub trait Layer<S>: 'static
where S: Subscriber,
{
Show 17 methods // Provided methods fn on_register_dispatch(&self, subscriber: &Dispatch) { ... } fn on_layer(&mut self, subscriber: &mut S) { ... } fn register_callsite( &self, metadata: &'static Metadata<'static>, ) -> Interest { ... } fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { ... } fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { ... } fn on_record(&self, _span: &Id, _values: &Record<'_>, _ctx: Context<'_, S>) { ... } fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>) { ... } fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, S>) -> bool { ... } fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, S>) { ... } fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>) { ... } fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>) { ... } fn on_close(&self, _id: Id, _ctx: Context<'_, S>) { ... } fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>) { ... } fn and_then<L>(self, layer: L) -> Layered<L, Self, S> where L: Layer<S>, Self: Sized { ... } fn with_subscriber(self, inner: S) -> Layered<Self, S> where Self: Sized { ... } fn with_filter<F>(self, filter: F) -> Filtered<Self, F, S> where Self: Sized, F: Filter<S> { ... } fn boxed(self) -> Box<dyn Layer<S> + Sync + Send> where Self: Sized + Layer<S> + Send + Sync + 'static, S: Subscriber { ... }
}
Expand description

A composable handler for tracing events.

A Layer implements a behavior for recording or collecting traces that can be composed together with other Layers to build a Subscriber. See the module-level documentation for details.

Provided Methods§

fn on_register_dispatch(&self, subscriber: &Dispatch)

Performs late initialization when installing this layer as a Subscriber.

§Avoiding Memory Leaks

Layers should not store the Dispatch pointing to the Subscriber that they are a part of. Because the Dispatch owns the Subscriber, storing the Dispatch within the Subscriber will create a reference count cycle, preventing the Dispatch from ever being dropped.

Instead, when it is necessary to store a cyclical reference to the Dispatch within a Layer, use Dispatch::downgrade to convert a Dispatch into a WeakDispatch. This type is analogous to std::sync::Weak, and does not create a reference count cycle. A WeakDispatch can be stored within a subscriber without causing a memory leak, and can be upgraded into a Dispatch temporarily when the Dispatch must be accessed by the subscriber.

fn on_layer(&mut self, subscriber: &mut S)

Performs late initialization when attaching a Layer to a Subscriber.

This is a callback that is called when the Layer is added to a Subscriber (e.g. in Layer::with_subscriber and SubscriberExt::with). Since this can only occur before the Subscriber has been set as the default, both the Layer and Subscriber are passed to this method mutably. This gives the Layer the opportunity to set any of its own fields with values recieved by method calls on the Subscriber.

For example, Filtered layers implement on_layer to call the Subscriber’s register_filter method, and store the returned FilterId as a field.

Note In most cases, Layer implementations will not need to implement this method. However, in cases where a type implementing Layer wraps one or more other types that implement Layer, like the Layered and Filtered types in this crate, that type MUST ensure that the inner Layers’ on_layer methods are called. Otherwise, functionality that relies on on_layer, such as per-layer filtering, may not work correctly.

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

Registers a new callsite with this layer, returning whether or not the layer is interested in being notified about the callsite, similarly to Subscriber::register_callsite.

By default, this returns Interest::always() if self.enabled returns true, or Interest::never() if it returns false.

Note: This method (and 
Layer::enabled) determine whether a span or event is
globally enabled, not whether the individual layer will be
notified about that span or event. This is intended to be used
by layers that implement filtering for the entire stack. Layers which do
not wish to be notified about certain spans or events but do not wish to
globally disable them should ignore those spans or events in their
on_event,
on_enter,
on_exit, and other notification
methods.

See the trait-level documentation for more information on filtering with Layers.

Layers may also implement this method to perform any behaviour that should be run once per callsite. If the layer wishes to use register_callsite for per-callsite behaviour, but does not want to globally enable or disable those callsites, it should always return Interest::always().

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

Returns true if this layer is interested in a span or event with the given metadata in the current Context, similarly to Subscriber::enabled.

By default, this always returns true, allowing the wrapped subscriber to choose to disable the span.

Note: This method (and 
Layer::register_callsite) determine whether a span or event is
globally enabled, not whether the individual layer will be
notified about that span or event. This is intended to be used
by layers that implement filtering for the entire stack. Layers which do
not wish to be notified about certain spans or events but do not wish to
globally disable them should ignore those spans or events in their
on_event,
on_enter,
on_exit, and other notification
methods.

See the trait-level documentation for more information on filtering with Layers.

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

Notifies this layer that a new span was constructed with the given Attributes and Id.

fn on_record(&self, _span: &Id, _values: &Record<'_>, _ctx: Context<'_, S>)

Notifies this layer that a span with the given Id recorded the given values.

fn on_follows_from(&self, _span: &Id, _follows: &Id, _ctx: Context<'_, S>)

Notifies this layer that a span with the ID span recorded that it follows from the span with the ID follows.

fn event_enabled(&self, _event: &Event<'_>, _ctx: Context<'_, S>) -> bool

Called before on_event, to determine if on_event should be called.

Note: This method determines whether an event is globally enabled, not whether the individual Layer will be notified about the event. This is intended to be used by Layers that implement filtering for the entire stack. Layers which do not wish to be notified about certain events but do not wish to globally disable them should ignore those events in their on_event.

See the trait-level documentation for more information on filtering with Layers.

fn on_event(&self, _event: &Event<'_>, _ctx: Context<'_, S>)

Notifies this layer that an event has occurred.

fn on_enter(&self, _id: &Id, _ctx: Context<'_, S>)

Notifies this layer that a span with the given ID was entered.

fn on_exit(&self, _id: &Id, _ctx: Context<'_, S>)

Notifies this layer that the span with the given ID was exited.

fn on_close(&self, _id: Id, _ctx: Context<'_, S>)

Notifies this layer that the span with the given ID has been closed.

fn on_id_change(&self, _old: &Id, _new: &Id, _ctx: Context<'_, S>)

Notifies this layer that a span ID has been cloned, and that the subscriber returned a different ID.

fn and_then<L>(self, layer: L) -> Layered<L, Self, S>
where L: Layer<S>, Self: Sized,

Composes this layer around the given Layer, returning a Layered struct implementing Layer.

The returned Layer will call the methods on this Layer and then those of the new Layer, before calling the methods on the subscriber it wraps. For example:

pub struct FooLayer {
    // ...
}

pub struct BarLayer {
    // ...
}

pub struct MySubscriber {
    // ...
}

impl<S: Subscriber> Layer<S> for FooLayer {
    // ...
}

impl<S: Subscriber> Layer<S> for BarLayer {
    // ...
}

let subscriber = FooLayer::new()
    .and_then(BarLayer::new())
    .with_subscriber(MySubscriber::new());

Multiple layers may be composed in this manner:

pub struct BazLayer {
    // ...
}

impl<S: Subscriber> Layer<S> for BazLayer {
    // ...
}

let subscriber = FooLayer::new()
    .and_then(BarLayer::new())
    .and_then(BazLayer::new())
    .with_subscriber(MySubscriber::new());

fn with_subscriber(self, inner: S) -> Layered<Self, S>
where Self: Sized,

Composes this Layer with the given Subscriber, returning a Layered struct that implements Subscriber.

The returned Layered subscriber will call the methods on this Layer and then those of the wrapped subscriber.

For example:

pub struct FooLayer {
    // ...
}

pub struct MySubscriber {
    // ...
}

impl<S: Subscriber> Layer<S> for FooLayer {
    // ...
}

let subscriber = FooLayer::new()
    .with_subscriber(MySubscriber::new());

fn with_filter<F>(self, filter: F) -> Filtered<Self, F, S>
where Self: Sized, F: Filter<S>,

Available on crate features registry and std only.

Combines self with a Filter, returning a Filtered layer.

The Filter will control which spans and events are enabled for this layer. See the trait-level documentation for details on per-layer filtering.

fn boxed(self) -> Box<dyn Layer<S> + Sync + Send>
where Self: Sized + Layer<S> + Send + Sync + 'static, S: Subscriber,

Available on crate features alloc or std only.

Erases the type of this Layer, returning a Boxed dyn Layer trait object.

This can be used when a function returns a Layer which may be of one of several types, or when a Layer subscriber has a very long type signature.

§Examples

The following example will not compile, because the value assigned to log_layer may have one of several different types:

use tracing_subscriber::{Layer, filter::LevelFilter, prelude::*};
use std::{path::PathBuf, fs::File, io};

/// Configures whether logs are emitted to a file, to stdout, or to stderr.
pub enum LogConfig {
    File(PathBuf),
    Stdout,
    Stderr,
}

let config = // ...

// Depending on the config, construct a layer of one of several types.
let log_layer = match config {
    // If logging to a file, use a maximally-verbose configuration.
    LogConfig::File(path) => {
        let file = File::create(path)?;
        tracing_subscriber::fmt::layer()
            .with_thread_ids(true)
            .with_thread_names(true)
            // Selecting the JSON logging format changes the layer's
            // type.
            .json()
            .with_span_list(true)
            // Setting the writer to use our log file changes the
            // layer's type again.
            .with_writer(file)
    },

    // If logging to stdout, use a pretty, human-readable configuration.
    LogConfig::Stdout => tracing_subscriber::fmt::layer()
        // Selecting the "pretty" logging format changes the
        // layer's type!
        .pretty()
        .with_writer(io::stdout)
        // Add a filter based on the RUST_LOG environment variable;
        // this changes the type too!
        .and_then(tracing_subscriber::EnvFilter::from_default_env()),

    // If logging to stdout, only log errors and warnings.
    LogConfig::Stderr => tracing_subscriber::fmt::layer()
        // Changing the writer changes the layer's type
        .with_writer(io::stderr)
        // Only log the `WARN` and `ERROR` levels. Adding a filter
        // changes the layer's type to `Filtered<LevelFilter, ...>`.
        .with_filter(LevelFilter::WARN),
};

tracing_subscriber::registry()
    .with(log_layer)
    .init();

However, adding a call to .boxed() after each match arm erases the layer’s type, so this code does compile:

let log_layer = match config {
    LogConfig::File(path) => {
        let file = File::create(path)?;
        tracing_subscriber::fmt::layer()
            .with_thread_ids(true)
            .with_thread_names(true)
            .json()
            .with_span_list(true)
            .with_writer(file)
            // Erase the type by boxing the layer
            .boxed()
    },

    LogConfig::Stdout => tracing_subscriber::fmt::layer()
        .pretty()
        .with_writer(io::stdout)
        .and_then(tracing_subscriber::EnvFilter::from_default_env())
        // Erase the type by boxing the layer
        .boxed(),

    LogConfig::Stderr => tracing_subscriber::fmt::layer()
        .with_writer(io::stderr)
        .with_filter(LevelFilter::WARN)
        // Erase the type by boxing the layer
        .boxed(),
};

tracing_subscriber::registry()
    .with(log_layer)
    .init();
Examples found in repository?
examples/app/log_layers.rs (line 28)
23
24
25
26
27
28
29
30
31
fn custom_layer(_app: &mut App) -> Option<BoxedLayer> {
    // You can provide multiple layers like this, since Vec<Layer> is also a layer:
    Some(Box::new(vec![
        bevy::log::tracing_subscriber::fmt::layer()
            .with_file(true)
            .boxed(),
        CustomLayer.boxed(),
    ]))
}
More examples
Hide additional examples
examples/app/log_layers_ecs.rs (line 90)
80
81
82
83
84
85
86
87
88
89
90
91
fn custom_layer(app: &mut App) -> Option<BoxedLayer> {
    let (sender, receiver) = mpsc::channel();

    let layer = CaptureLayer { sender };
    let resource = CapturedLogEvents(receiver);

    app.insert_non_send_resource(resource);
    app.add_event::<LogEvent>();
    app.add_systems(Update, transfer_log_events);

    Some(layer.boxed())
}

Trait Implementations§

§

impl<S> Layer<S> for Box<dyn Layer<S> + Sync + Send>
where S: Subscriber,

Available on crate features std or alloc only.
§

fn on_register_dispatch(&self, subscriber: &Dispatch)

Performs late initialization when installing this layer as a Subscriber. Read more
§

fn on_layer(&mut self, subscriber: &mut S)

Performs late initialization when attaching a Layer to a Subscriber. Read more
§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

Notifies this layer that a new span was constructed with the given Attributes and Id.
§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

Registers a new callsite with this layer, returning whether or not the layer is interested in being notified about the callsite, similarly to Subscriber::register_callsite. Read more
§

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

Returns true if this layer is interested in a span or event with the given metadata in the current Context, similarly to Subscriber::enabled. Read more
§

fn on_record(&self, span: &Id, values: &Record<'_>, ctx: Context<'_, S>)

Notifies this layer that a span with the given Id recorded the given values.
§

fn on_follows_from(&self, span: &Id, follows: &Id, ctx: Context<'_, S>)

Notifies this layer that a span with the ID span recorded that it follows from the span with the ID follows.
§

fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool

Called before on_event, to determine if on_event should be called.
§

fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)

Notifies this layer that an event has occurred.
§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

Notifies this layer that a span with the given ID was entered.
§

fn on_exit(&self, id: &Id, ctx: Context<'_, S>)

Notifies this layer that the span with the given ID was exited.
§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

Notifies this layer that the span with the given ID has been closed.
§

fn on_id_change(&self, old: &Id, new: &Id, ctx: Context<'_, S>)

Notifies this layer that a span ID has been cloned, and that the subscriber returned a different ID.
§

fn and_then<L>(self, layer: L) -> Layered<L, Self, S>
where L: Layer<S>, Self: Sized,

Composes this layer around the given Layer, returning a Layered struct implementing Layer. Read more
§

fn with_subscriber(self, inner: S) -> Layered<Self, S>
where Self: Sized,

Composes this Layer with the given Subscriber, returning a Layered struct that implements Subscriber. Read more
§

fn with_filter<F>(self, filter: F) -> Filtered<Self, F, S>
where Self: Sized, F: Filter<S>,

Available on crate features registry and std only.
Combines self with a Filter, returning a Filtered layer. Read more
§

fn boxed(self) -> Box<dyn Layer<S> + Sync + Send>
where Self: Sized + Layer<S> + Send + Sync + 'static, S: Subscriber,

Available on crate features alloc or std only.
Erases the type of this Layer, returning a Boxed dyn Layer trait object. Read more

Implementations on Foreign Types§

§

impl<L, S> Layer<S> for Option<L>
where L: Layer<S>, S: Subscriber,

§

fn on_layer(&mut self, subscriber: &mut S)

§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

§

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

§

fn on_record(&self, span: &Id, values: &Record<'_>, ctx: Context<'_, S>)

§

fn on_follows_from(&self, span: &Id, follows: &Id, ctx: Context<'_, S>)

§

fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool

§

fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)

§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_exit(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

§

fn on_id_change(&self, old: &Id, new: &Id, ctx: Context<'_, S>)

§

impl<L, S> Layer<S> for Box<L>
where L: Layer<S>, S: Subscriber,

Available on crate features std or alloc only.
§

fn on_register_dispatch(&self, subscriber: &Dispatch)

§

fn on_layer(&mut self, subscriber: &mut S)

§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

§

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

§

fn on_record(&self, span: &Id, values: &Record<'_>, ctx: Context<'_, S>)

§

fn on_follows_from(&self, span: &Id, follows: &Id, ctx: Context<'_, S>)

§

fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool

§

fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)

§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_exit(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

§

fn on_id_change(&self, old: &Id, new: &Id, ctx: Context<'_, S>)

§

impl<S> Layer<S> for Box<dyn Layer<S> + Sync + Send>
where S: Subscriber,

Available on crate features std or alloc only.
§

fn on_register_dispatch(&self, subscriber: &Dispatch)

§

fn on_layer(&mut self, subscriber: &mut S)

§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

§

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

§

fn on_record(&self, span: &Id, values: &Record<'_>, ctx: Context<'_, S>)

§

fn on_follows_from(&self, span: &Id, follows: &Id, ctx: Context<'_, S>)

§

fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool

§

fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)

§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_exit(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

§

fn on_id_change(&self, old: &Id, new: &Id, ctx: Context<'_, S>)

§

impl<S> Layer<S> for ChromeLayer<S>
where S: Subscriber + for<'span> LookupSpan<'span> + Send + Sync,

§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>)

§

fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>)

§

fn on_exit(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

§

impl<S, C> Layer<S> for TracyLayer<C>
where S: Subscriber + for<'a> LookupSpan<'a>, C: Config + 'static,

§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

§

fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>)

§

fn on_event(&self, event: &Event<'_>, _: Context<'_, S>)

§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_exit(&self, id: &Id, _: Context<'_, S>)

§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

source§

impl<S, F> Layer<S> for ErrorLayer<S, F>
where S: Subscriber + for<'span> LookupSpan<'span>, F: for<'writer> FormatFields<'writer> + 'static,

source§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

Notifies this layer that a new span was constructed with the given Attributes and Id.

§

impl<S, L> Layer<S> for Vec<L>
where L: Layer<S>, S: Subscriber,

Available on crate features std or alloc only.
§

fn on_layer(&mut self, subscriber: &mut S)

§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

§

fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool

§

fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool

§

fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>)

§

fn on_record(&self, span: &Id, values: &Record<'_>, ctx: Context<'_, S>)

§

fn on_follows_from(&self, span: &Id, follows: &Id, ctx: Context<'_, S>)

§

fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)

§

fn on_enter(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_exit(&self, id: &Id, ctx: Context<'_, S>)

§

fn on_close(&self, id: Id, ctx: Context<'_, S>)

Implementors§

§

impl<L, S> Layer<S> for bevy::log::tracing_subscriber::reload::Layer<L, S>
where L: Layer<S> + 'static, S: Subscriber,

§

impl<S> Layer<S> for LevelFilter
where S: Subscriber,

§

impl<S> Layer<S> for Targets
where S: Subscriber,

§

impl<S> Layer<S> for Identity
where S: Subscriber,

§

impl<S> Layer<S> for EnvFilter
where S: Subscriber,

§

impl<S, A, B> Layer<S> for Layered<A, B, S>
where A: Layer<S>, B: Layer<S>, S: Subscriber,

§

impl<S, F> Layer<S> for FilterFn<F>
where F: Fn(&Metadata<'_>) -> bool + 'static, S: Subscriber,

§

impl<S, F, R> Layer<S> for DynFilterFn<S, F, R>
where F: Fn(&Metadata<'_>, &Context<'_, S>) -> bool + 'static, R: Fn(&'static Metadata<'static>) -> Interest + 'static, S: Subscriber,

§

impl<S, L, F> Layer<S> for Filtered<L, F, S>
where S: Subscriber + for<'span> LookupSpan<'span> + 'static, F: Filter<S> + 'static, L: Layer<S>,

§

impl<S, N, E, W> Layer<S> for bevy::log::tracing_subscriber::fmt::Layer<S, N, E, W>
where S: Subscriber + for<'a> LookupSpan<'a>, N: for<'writer> FormatFields<'writer> + 'static, E: FormatEvent<S, N> + 'static, W: for<'writer> MakeWriter<'writer> + 'static,