mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-09-29 22:10:38 +00:00
subscriber: improve docs on Layer
composition (#566)
Depends on #564 This commit adds a new section to the `Layer` docs on how `Layer`s and `Subscriber`s are composed. Additionally, it updates the docs to prefer the use of `SubscriberExt::with` over `Layer::with_subscriber`. Additionally, I've fixed how `SubscriberExt::with` is implemented, so that `Layer`s may use `with_subscriber` as a callback for composition. Closes #452 Closes #505 (IMO)
This commit is contained in:
parent
a661155590
commit
e32012a64a
@ -20,8 +20,8 @@ use tracing_core::{
|
||||
/// use tracing_subscriber::{fmt, registry::Registry};
|
||||
/// use tracing_subscriber::prelude::*;
|
||||
///
|
||||
/// let subscriber = fmt::Layer::default()
|
||||
/// .with_subscriber(Registry::default());
|
||||
/// let subscriber = Registry::default()
|
||||
/// .with(fmt::Layer::default());
|
||||
///
|
||||
/// tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
/// ```
|
||||
|
@ -101,16 +101,18 @@
|
||||
//!
|
||||
//! ```rust
|
||||
//! use tracing_subscriber::{fmt, Layer, registry::Registry, EnvFilter};
|
||||
//! use tracing_subscriber::prelude::*;
|
||||
//!
|
||||
//! let fmt_layer = fmt::Layer::builder()
|
||||
//! .with_target(false)
|
||||
//! .finish();
|
||||
//!
|
||||
//! let subscriber = EnvFilter::try_from_default_env()
|
||||
//! let filter_layer = EnvFilter::try_from_default_env()
|
||||
//! .or_else(|_| EnvFilter::try_new("info"))
|
||||
//! .unwrap()
|
||||
//! .and_then(fmt_layer)
|
||||
//! .with_subscriber(Registry::default());
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let subscriber = Registry::default()
|
||||
//! .with(filter_layer)
|
||||
//! .with(fmt_layer);
|
||||
//!
|
||||
//! tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
//! ```
|
||||
|
@ -31,6 +31,131 @@ use std::{any::TypeId, marker::PhantomData};
|
||||
/// [`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.
|
||||
///
|
||||
/// `Layer`s 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:
|
||||
/// ```rust
|
||||
/// use tracing_subscriber::Layer;
|
||||
/// use tracing_subscriber::prelude::*;
|
||||
/// use tracing::Subscriber;
|
||||
///
|
||||
/// pub struct MyLayer {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// impl<S: Subscriber> Layer<S> for MyLayer {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// pub struct MySubscriber {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event};
|
||||
/// impl Subscriber for MySubscriber {
|
||||
/// // ...
|
||||
/// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) }
|
||||
/// # fn record(&self, _: &Id, _: &Record) {}
|
||||
/// # fn event(&self, _: &Event) {}
|
||||
/// # fn record_follows_from(&self, _: &Id, _: &Id) {}
|
||||
/// # fn enabled(&self, _: &Metadata) -> bool { false }
|
||||
/// # fn enter(&self, _: &Id) {}
|
||||
/// # fn exit(&self, _: &Id) {}
|
||||
/// }
|
||||
/// # impl MyLayer {
|
||||
/// # fn new() -> Self { Self {} }
|
||||
/// # }
|
||||
/// # impl MySubscriber {
|
||||
/// # fn new() -> Self { Self { }}
|
||||
/// # }
|
||||
///
|
||||
/// let subscriber = MySubscriber::new()
|
||||
/// .with(MyLayer::new());
|
||||
///
|
||||
/// tracing::subscriber::set_global_default(subscriber);
|
||||
/// ```
|
||||
///
|
||||
/// Multiple `Layer`s may be composed in the same manner:
|
||||
/// ```rust
|
||||
/// # use tracing_subscriber::Layer;
|
||||
/// # use tracing_subscriber::prelude::*;
|
||||
/// # use tracing::Subscriber;
|
||||
/// pub struct MyOtherLayer {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// impl<S: Subscriber> Layer<S> for MyOtherLayer {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// pub struct MyThirdLayer {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// impl<S: Subscriber> Layer<S> for MyThirdLayer {
|
||||
/// // ...
|
||||
/// }
|
||||
/// # pub struct MyLayer {}
|
||||
/// # impl<S: Subscriber> Layer<S> for MyLayer {}
|
||||
/// # pub struct MySubscriber { }
|
||||
/// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event};
|
||||
/// # impl Subscriber for MySubscriber {
|
||||
/// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(1) }
|
||||
/// # fn record(&self, _: &Id, _: &Record) {}
|
||||
/// # fn event(&self, _: &Event) {}
|
||||
/// # fn record_follows_from(&self, _: &Id, _: &Id) {}
|
||||
/// # fn enabled(&self, _: &Metadata) -> bool { false }
|
||||
/// # fn enter(&self, _: &Id) {}
|
||||
/// # fn exit(&self, _: &Id) {}
|
||||
/// }
|
||||
/// # impl MyLayer {
|
||||
/// # fn new() -> Self { Self {} }
|
||||
/// # }
|
||||
/// # impl MyOtherLayer {
|
||||
/// # fn new() -> Self { Self {} }
|
||||
/// # }
|
||||
/// # impl MyThirdLayer {
|
||||
/// # fn new() -> Self { Self {} }
|
||||
/// # }
|
||||
/// # impl MySubscriber {
|
||||
/// # fn new() -> Self { Self { }}
|
||||
/// # }
|
||||
///
|
||||
/// let subscriber = MySubscriber::new()
|
||||
/// .with(MyLayer::new())
|
||||
/// .with(MyOtherLayer::new())
|
||||
/// .with(MyThirdLayer::new());
|
||||
///
|
||||
/// tracing::subscriber::set_global_default(subscriber);
|
||||
/// ```
|
||||
///
|
||||
/// The [`Layer::with_subscriber` method][with-sub] 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, `Layer`s which wish to perform
|
||||
/// additional behavior when composed with a subscriber may provide their own
|
||||
/// implementations of `SubscriberExt::with`.
|
||||
///
|
||||
/// [`SubscriberExt::with`]: trait.SubscriberExt.html#method.with
|
||||
/// [`Layered`]: struct.Layered.html
|
||||
/// [prelude]: ../prelude/index.html
|
||||
/// [with-sub]: #method.with_subscriber
|
||||
///
|
||||
/// ## Recording Traces
|
||||
///
|
||||
/// The `Layer` trait defines a set of methods for consuming notifications from
|
||||
@ -371,11 +496,7 @@ pub trait SubscriberExt: Subscriber + crate::sealed::Sealed {
|
||||
L: Layer<Self>,
|
||||
Self: Sized,
|
||||
{
|
||||
Layered {
|
||||
layer,
|
||||
inner: self,
|
||||
_s: PhantomData,
|
||||
}
|
||||
layer.with_subscriber(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
//!
|
||||
//! For example, we might create a `Registry` and add multiple `Layer`s like so:
|
||||
//! ```rust
|
||||
//! use tracing_subscriber::{registry::Registry, Layer};
|
||||
//! use tracing_subscriber::{registry::Registry, Layer, prelude::*};
|
||||
//! # use tracing_core::Subscriber;
|
||||
//! # pub struct FooLayer {}
|
||||
//! # pub struct BarLayer {}
|
||||
@ -23,12 +23,12 @@
|
||||
//! # fn new() -> Self { Self {} }
|
||||
//! # }
|
||||
//! # impl BarLayer {
|
||||
//! # fn new() -> Self { Self { }}
|
||||
//! # fn new() -> Self { Self {} }
|
||||
//! # }
|
||||
//!
|
||||
//! let subscriber = FooLayer::new()
|
||||
//! .and_then(BarLayer::new())
|
||||
//! .with_subscriber(Registry::default());
|
||||
//! let subscriber = Registry::default()
|
||||
//! .with(FooLayer::new())
|
||||
//! .with(BarLayer::new());
|
||||
//! ```
|
||||
//!
|
||||
//! If a type implementing `Layer` depends on the functionality of a `Registry`
|
||||
|
Loading…
x
Reference in New Issue
Block a user