logo
pub trait Layer<S> where
    S: Subscriber,
    Self: 'static, 
{ fn register_callsite(
        &self,
        metadata: &'static Metadata<'static>
    ) -> Interest { ... }
fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { ... }
fn 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>) { ... }
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
, { ... } }
Expand description

A composable handler for tracing events.

The Subscriber trait in tracing-core represents the complete set of functionality required to consume tracing instrumentation. This means that a single Subscriber instance is a self-contained implementation of a complete strategy for collecting traces; but it also means that the Subscriber trait cannot easily be composed with other Subscribers.

In particular, Subscriber’s are responsible for generating span IDs and assigning them to spans. Since these IDs must uniquely identify a span within the context of the current trace, this means that there may only be a single Subscriber for a given thread at any point in time — otherwise, there would be no authoritative source of span IDs.

On the other hand, the majority of the Subscriber trait’s functionality is composable: any number of subscribers may observe events, span entry and exit, and so on, provided that there is a single authoritative source of span IDs. The Layer trait represents this composable subset of the Subscriber behavior; it can observe events and spans, but does not assign IDs.

Composing Layers

Since a Layer does not implement a complete strategy for collecting traces, it must be composed with a Subscriber in order to be used. The Layer trait is generic over a type parameter (called S in the trait definition), representing the types of Subscriber they can be composed with. Thus, a Layer may be implemented that will only compose with a particular Subscriber implementation, or additional trait bounds may be added to constrain what types implementing Subscriber a Layer can wrap.

Layers may be added to a Subscriber by using the SubscriberExt::with method, which is provided by tracing-subscriber’s prelude. This method returns a Layered struct that implements Subscriber by composing the Layer with the Subscriber.

For example:

use tracing_subscriber::Layer;
use tracing_subscriber::prelude::*;
use tracing::Subscriber;

pub struct MyLayer {
    // ...
}

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

pub struct MySubscriber {
    // ...
}

impl Subscriber for MySubscriber {
    // ...
}

let subscriber = MySubscriber::new()
    .with(MyLayer::new());

tracing::subscriber::set_global_default(subscriber);

Multiple Layers may be composed in the same manner:

pub struct MyOtherLayer {
    // ...
}

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

pub struct MyThirdLayer {
    // ...
}

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

let subscriber = MySubscriber::new()
    .with(MyLayer::new())
    .with(MyOtherLayer::new())
    .with(MyThirdLayer::new());

tracing::subscriber::set_global_default(subscriber);

The Layer::with_subscriber method constructs the Layered type from a Layer and Subscriber, and is called by SubscriberExt::with. In general, it is more idiomatic to use SubscriberExt::with, and treat Layer::with_subscriber as an implementation detail, as with_subscriber calls must be nested, leading to less clear code for the reader. However, Layers which wish to perform additional behavior when composed with a subscriber may provide their own implementations of SubscriberExt::with.

Recording Traces

The Layer trait defines a set of methods for consuming notifications from tracing instrumentation, which are generally equivalent to the similarly named methods on Subscriber. Unlike Subscriber, the methods on Layer are additionally passed a Context type, which exposes additional information provided by the wrapped subscriber (such as the current span) to the layer.

Filtering with Layers

As well as strategies for handling trace events, the Layer trait may also be used to represent composable filters. This allows the determination of what spans and events should be recorded to be decoupled from how they are recorded: a filtering layer can be applied to other layers or subscribers. A Layer that implements a filtering strategy should override the register_callsite and/or enabled methods. It may also choose to implement methods such as on_enter, if it wishes to filter trace events based on the current span context.

Note that the Layer::register_callsite and Layer::enabled methods determine whether a span or event is enabled globally. Thus, they should not be used to indicate whether an individual layer wishes to record a particular span or event. Instead, if a layer is only interested in a subset of trace data, but does not wish to disable other spans and events for the rest of the layer stack should ignore those spans and events in its notification methods.

The filtering methods on a stack of Layers are evaluated in a top-down order, starting with the outermost Layer and ending with the wrapped Subscriber. If any layer returns false from its enabled method, or Interest::never() from its register_callsite method, filter evaluation will short-circuit and the span or event will be disabled.

Provided methods

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().

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.

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

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

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

Notifies this layer that an event has occurred.

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

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

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

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

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());

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());

Implementations on Foreign Types

Implementors