diff --git a/tracing-fmt/Cargo.toml b/tracing-fmt/Cargo.toml index 0a0215a36b..89c863da61 100644 --- a/tracing-fmt/Cargo.toml +++ b/tracing-fmt/Cargo.toml @@ -19,4 +19,4 @@ lock_api = "0.1" chrono = { version = "0.4", optional = true } [dev-dependencies] -tracing = "0.1" +tracing = { version = "0.1", path = "../tracing" } diff --git a/tracing-macros/Cargo.toml b/tracing-macros/Cargo.toml index c930737ad6..762bfe833b 100644 --- a/tracing-macros/Cargo.toml +++ b/tracing-macros/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Eliza Weisman "] edition = "2018" [dependencies] -tracing = "0.1" +tracing = { version = "0.1", path = "../tracing" } [dev-dependencies] tracing-log = { path = "../tracing-log" } diff --git a/tracing-proc-macros/Cargo.toml b/tracing-proc-macros/Cargo.toml index 15a662f918..c59e0ea983 100644 --- a/tracing-proc-macros/Cargo.toml +++ b/tracing-proc-macros/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Eliza Weisman ", "David Barsky "] edition = "2018" [dependencies] -tracing = "0.1" +tracing-core = "0.1.2" [dev-dependencies] tracing-log = { path = "../tracing-log" } +tracing = "0.1" diff --git a/tracing-subscriber/src/layer.rs b/tracing-subscriber/src/layer.rs new file mode 100644 index 0000000000..40b6ac5f39 --- /dev/null +++ b/tracing-subscriber/src/layer.rs @@ -0,0 +1,699 @@ +use tracing_core::{ + metadata::Metadata, + span, + subscriber::{Interest, Subscriber}, + Event, +}; + +use std::{any::TypeId, marker::PhantomData}; + +/// 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 `Subscriber`s. +/// +/// 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. +/// +/// ## 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 `Layer`s +/// +/// 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 `Layer`s 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. +/// +/// [`Subscriber`]: https://docs.rs/tracing-core/0.1.1/tracing_core/subscriber/trait.Subscriber.html +/// [span IDs]: https://docs.rs/tracing-core/0.1.1/tracing_core/span/struct.Id.html +/// [`Context`]: struct.Context.html +/// [the current span]: struct.Context.html#method.current_span +/// [`register_callsite`]: #method.register_callsite +/// [`enabled`]: #method.enabled +/// [`on_enter`]: #method.on_enter +/// [`Layer::register_callsite`]: #method.register_callsite +/// [`Layer::enabled`]: #method.enabled +/// [`Interest::never()`]: https://docs.rs/tracing-core/0.1.1/tracing_core/subscriber/struct.Interest.html#method.never +pub trait Layer +where + S: Subscriber, + Self: 'static, +{ + /// 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 `Layer`s. + /// + /// 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()`]. + /// + /// [`Interest`]: https://docs.rs/tracing-core/0.1.1/tracing_core/struct.Interest.html + /// [`Subscriber::register_callsite`]: https://docs.rs/tracing-core/0.1.1/tracing_core/trait.Subscriber.html#method.register_callsite + /// [`Interest::never()`]: https://docs.rs/tracing-core/0.1.1/tracing_core/subscriber/struct.Interest.html#method.never + /// [`Interest::never()`]: https://docs.rs/tracing-core/0.1.1/tracing_core/subscriber/struct.Interest.html#method.always + /// [`self.enabled`]: #method.enabled + /// [`Layer::enabled`]: #method.enabled + /// [`on_event`]: #method.on_event + /// [`on_enter`]: #method.on_enter + /// [`on_exit`]: #method.on_exit + /// [the trait-level documentation]: #filtering-with-layers + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + if self.enabled(metadata, Context::none()) { + Interest::always() + } else { + Interest::never() + } + } + + /// 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 `Layer`s. + /// + /// [`Interest`]: https://docs.rs/tracing-core/0.1.1/tracing_core/struct.Interest.html + /// [`Context`]: ../struct.Context.html + /// [`Subscriber::enabled`]: https://docs.rs/tracing-core/0.1.1/tracing_core/trait.Subscriber.html#method.enabled + /// [`Layer::register_callsite`]: #method.reegister_callsite + /// [`on_event`]: #method.on_event + /// [`on_enter`]: #method.on_enter + /// [`on_exit`]: #method.on_exit + /// [the trait-level documentation]: #filtering-with-layers + fn enabled(&self, _metadata: &Metadata, _ctx: Context) -> bool { + true + } + + /// Notifies this layer that a new span was constructed with the given + /// `Attributes` and `Id`. + fn new_span(&self, _attrs: &span::Attributes, _id: &span::Id, _ctx: Context) {} + + /// Notifies this layer that a span with the given `Id` recorded the given + /// `values`. + // Note: it's unclear to me why we'd need the current span in `record` (the + // only thing the `Context` type currently provides), but passing it in anyway + // seems like a good future-proofing measure as it may grow other methods later... + fn on_record(&self, _span: &span::Id, _values: &span::Record, _ctx: Context) {} + + /// Notifies this layer that a span with the ID `span` recorded that it + /// follows from the span with the ID `follows`. + // Note: it's unclear to me why we'd need the current span in `record` (the + // only thing the `Context` type currently provides), but passing it in anyway + // seems like a good future-proofing measure as it may grow other methods later... + fn on_follows_from(&self, _span: &span::Id, _follows: &span::Id, _ctx: Context) {} + + /// Notifies this layer that an event has occurred. + fn on_event(&self, _event: &Event, _ctx: Context) {} + + /// Notifies this layer that a span with the given ID was entered. + fn on_enter(&self, _id: &span::Id, _ctx: Context) {} + + /// Notifies this layer that the span with the given ID was exited. + fn on_exit(&self, _id: &span::Id, _ctx: Context) {} + + /// Notifies this layer that the span with the given ID has been closed. + fn on_close(&self, _id: span::Id, _ctx: Context) {} + + /// Notifies this layer that a span ID has been cloned, and that the + /// subscriber returned a different ID. + fn on_id_change(&self, _old: &span::Id, _new: &span::Id, _ctx: Context) {} + + /// 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: + /// ```rust + /// # use tracing_subscriber::layer::Layer; + /// # use tracing_core::Subscriber; + /// # fn main() { + /// pub struct FooLayer { + /// // ... + /// } + /// + /// pub struct BarLayer { + /// // ... + /// } + /// + /// pub struct MySubscriber { + /// // ... + /// } + /// + /// impl Layer for FooLayer { + /// // ... + /// } + /// + /// impl Layer for BarLayer { + /// // ... + /// } + /// + /// # impl FooLayer { + /// # fn new() -> Self { Self {} } + /// # } + /// # impl BarLayer { + /// # fn new() -> Self { Self { }} + /// # } + /// # impl MySubscriber { + /// # fn new() -> Self { Self { }} + /// # } + /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; + /// # impl tracing_core::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) {} + /// # } + /// let subscriber = FooLayer::new() + /// .and_then(BarLayer::new()) + /// .with_subscriber(MySubscriber::new()); + /// # } + /// ``` + /// + /// Multiple layers may be composed in this manner: + /// /// ```rust + /// # use tracing_subscriber::layer::Layer; + /// # use tracing_core::Subscriber; + /// # fn main() { + /// # pub struct FooLayer {} + /// # pub struct BarLayer {} + /// # pub struct MySubscriber {} + /// # impl Layer for FooLayer {} + /// # impl Layer for BarLayer {} + /// # impl FooLayer { + /// # fn new() -> Self { Self {} } + /// # } + /// # impl BarLayer { + /// # fn new() -> Self { Self { }} + /// # } + /// # impl MySubscriber { + /// # fn new() -> Self { Self { }} + /// # } + /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata, Event}; + /// # impl tracing_core::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) {} + /// # } + /// pub struct BazLayer { + /// // ... + /// } + /// + /// impl Layer for BazLayer { + /// // ... + /// } + /// # impl BazLayer { fn new() -> Self { BazLayer } } + /// + /// let subscriber = FooLayer::new() + /// .and_then(BarLayer::new()) + /// .and_then(BazLayer::new()) + /// .with_subscriber(MySubscriber::new()); + /// # } + /// ``` + fn and_then(self, layer: L) -> Layered + where + L: Layer, + Self: Sized, + { + Layered { + layer, + inner: self, + _s: PhantomData, + } + } + + /// 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: + /// ```rust + /// # use tracing_subscriber::layer::Layer; + /// # use tracing_core::Subscriber; + /// # fn main() { + /// pub struct FooLayer { + /// // ... + /// } + /// + /// pub struct MySubscriber { + /// // ... + /// } + /// + /// impl Layer for FooLayer { + /// // ... + /// } + /// + /// # impl FooLayer { + /// # fn new() -> Self { Self {} } + /// # } + /// # impl MySubscriber { + /// # fn new() -> Self { Self { }} + /// # } + /// # use tracing_core::{span::{Id, Attributes, Record}, Metadata}; + /// # impl tracing_core::Subscriber for MySubscriber { + /// # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) } + /// # fn record(&self, _: &Id, _: &Record) {} + /// # fn event(&self, _: &tracing_core::Event) {} + /// # fn record_follows_from(&self, _: &Id, _: &Id) {} + /// # fn enabled(&self, _: &Metadata) -> bool { false } + /// # fn enter(&self, _: &Id) {} + /// # fn exit(&self, _: &Id) {} + /// # } + /// let subscriber = FooLayer::new() + /// .with_subscriber(MySubscriber::new()); + /// # } + fn with_subscriber(self, inner: S) -> Layered + where + Self: Sized, + { + Layered { + layer: self, + inner, + _s: PhantomData, + } + } + + #[doc(hidden)] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + if id == TypeId::of::() { + Some(&self as *const _ as *const ()) + } else { + None + } + } +} + +pub trait SubscriberExt: Subscriber + crate::sealed::Sealed { + fn with(self, layer: L) -> Layered + where + L: Layer, + Self: Sized, + { + Layered { + layer, + inner: self, + _s: PhantomData, + } + } +} + +/// Represents information about the current context provided to `Layer`s by the +/// wrapped `Subscriber`. +#[derive(Debug)] +pub struct Context<'a, S> { + subscriber: Option<&'a S>, +} + +#[derive(Clone, Debug)] +pub struct Layered { + layer: L, + inner: I, + _s: PhantomData, +} + +// === impl Layered === + +impl Subscriber for Layered +where + L: Layer, + S: Subscriber, +{ + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + let outer = self.layer.register_callsite(metadata); + if outer.is_never() { + // if the outer layer has disabled the callsite, return now so that + // the subscriber doesn't get its hopes up. + return outer; + } + + let inner = self.inner.register_callsite(metadata); + if outer.is_sometimes() { + // if this interest is "sometimes", return "sometimes" to ensure that + // filters are reevaluated. + outer + } else { + // otherwise, allow the inner subscriber to weigh in. + inner + } + } + + fn enabled(&self, metadata: &Metadata) -> bool { + if self.layer.enabled(metadata, self.ctx()) { + // if the outer layer enables the callsite metadata, ask the subscriber. + self.inner.enabled(metadata) + } else { + // otherwise, the callsite is disabled by the layer + false + } + } + + fn new_span(&self, span: &span::Attributes) -> span::Id { + let id = self.inner.new_span(span); + self.layer.new_span(span, &id, self.ctx()); + id + } + + fn record(&self, span: &span::Id, values: &span::Record) { + self.inner.record(span, values); + self.layer.on_record(span, values, self.ctx()); + } + + fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { + self.inner.record_follows_from(span, follows); + self.layer.on_follows_from(span, follows, self.ctx()); + } + + fn event(&self, event: &Event) { + self.inner.event(event); + self.layer.on_event(event, self.ctx()); + } + + fn enter(&self, span: &span::Id) { + self.inner.enter(span); + self.layer.on_enter(span, self.ctx()); + } + + fn exit(&self, span: &span::Id) { + self.inner.exit(span); + self.layer.on_exit(span, self.ctx()); + } + + fn clone_span(&self, old: &span::Id) -> span::Id { + let new = self.inner.clone_span(old); + if &new != old { + self.layer.on_id_change(old, &new, self.ctx()) + }; + new + } + + #[inline] + fn drop_span(&self, id: span::Id) { + self.try_close(id); + } + + fn try_close(&self, id: span::Id) -> bool { + let id2 = id.clone(); + if self.inner.try_close(id) { + self.layer.on_close(id2, self.ctx()); + true + } else { + false + } + } + + #[doc(hidden)] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + self.layer + .downcast_raw(id) + .or_else(|| self.inner.downcast_raw(id)) + } +} + +impl Layer for Layered +where + A: Layer, + B: Layer, + S: Subscriber, +{ + fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { + let outer = self.layer.register_callsite(metadata); + if outer.is_never() { + // if the outer layer has disabled the callsite, return now so that + // inner layers don't get their hopes up. + return outer; + } + + let inner = self.inner.register_callsite(metadata); + if outer.is_sometimes() { + // if this interest is "sometimes", return "sometimes" to ensure that + // filters are reevaluated. + outer + } else { + // otherwise, allow the inner layer to weigh in. + inner + } + } + + fn enabled(&self, metadata: &Metadata, ctx: Context) -> bool { + if self.layer.enabled(metadata, ctx.clone()) { + // if the outer layer enables the callsite metadata, ask the inner layer. + self.inner.enabled(metadata, ctx) + } else { + // otherwise, the callsite is disabled by this layer + false + } + } + + #[inline] + fn new_span(&self, attrs: &span::Attributes, id: &span::Id, ctx: Context) { + self.inner.new_span(attrs, id, ctx.clone()); + self.layer.new_span(attrs, id, ctx); + } + + #[inline] + fn on_record(&self, span: &span::Id, values: &span::Record, ctx: Context) { + self.inner.on_record(span, values, ctx.clone()); + self.layer.on_record(span, values, ctx); + } + + #[inline] + fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context) { + self.inner.on_follows_from(span, follows, ctx.clone()); + self.layer.on_follows_from(span, follows, ctx); + } + + #[inline] + fn on_event(&self, event: &Event, ctx: Context) { + self.inner.on_event(event, ctx.clone()); + self.layer.on_event(event, ctx); + } + + #[inline] + fn on_enter(&self, id: &span::Id, ctx: Context) { + self.inner.on_enter(id, ctx.clone()); + self.layer.on_enter(id, ctx); + } + + #[inline] + fn on_exit(&self, id: &span::Id, ctx: Context) { + self.inner.on_exit(id, ctx.clone()); + self.layer.on_exit(id, ctx); + } + + #[inline] + fn on_close(&self, id: span::Id, ctx: Context) { + self.inner.on_close(id.clone(), ctx.clone()); + self.layer.on_close(id, ctx); + } + + #[inline] + fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context) { + self.inner.on_id_change(old, new, ctx.clone()); + self.layer.on_id_change(old, new, ctx); + } + + #[doc(hidden)] + unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { + self.layer + .downcast_raw(id) + .or_else(|| self.inner.downcast_raw(id)) + } +} + +impl Layered +where + S: Subscriber, +{ + fn ctx(&self) -> Context { + Context { + subscriber: Some(&self.inner), + } + } +} + +// === impl SubscriberExt === + +impl crate::sealed::Sealed for S {} +impl SubscriberExt for S {} + +// === impl Context === + +impl<'a, S: Subscriber> Context<'a, S> { + /// Returns the wrapped subscriber's view of the current span. + #[inline] + pub fn current_span(&self) -> span::Current { + self.subscriber + .map(Subscriber::current_span) + // TODO: this would be more correct as "unknown", so perhaps + // `tracing-core` should make `Current::unknown()` public? + .unwrap_or_else(span::Current::none) + } +} + +impl<'a, S> Context<'a, S> { + pub(crate) fn none() -> Self { + Self { subscriber: None } + } +} + +impl<'a, S> Clone for Context<'a, S> { + #[inline] + fn clone(&self) -> Self { + let subscriber = if let Some(ref subscriber) = self.subscriber { + Some(*subscriber) + } else { + None + }; + Context { subscriber } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct NopSubscriber; + + impl Subscriber for NopSubscriber { + fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest { + Interest::never() + } + + fn enabled(&self, _: &Metadata) -> bool { + false + } + + fn new_span(&self, _: &span::Attributes) -> span::Id { + span::Id::from_u64(1) + } + + fn record(&self, _: &span::Id, _: &span::Record) {} + fn record_follows_from(&self, _: &span::Id, _: &span::Id) {} + fn event(&self, _: &Event) {} + fn enter(&self, _: &span::Id) {} + fn exit(&self, _: &span::Id) {} + } + + struct NopLayer; + impl Layer for NopLayer {} + + struct NopLayer2; + impl Layer for NopLayer2 {} + + fn assert_subscriber(_s: impl Subscriber) {} + + #[test] + fn layer_is_subscriber() { + let s = NopLayer.with_subscriber(NopSubscriber); + assert_subscriber(s) + } + + #[test] + fn two_layers_are_subscriber() { + let s = NopLayer.and_then(NopLayer).with_subscriber(NopSubscriber); + assert_subscriber(s) + } + + #[test] + fn three_layers_are_subscriber() { + let s = NopLayer + .and_then(NopLayer) + .and_then(NopLayer) + .with_subscriber(NopSubscriber); + assert_subscriber(s) + } + + #[test] + fn downcasts_to_subscriber() { + let s = NopLayer + .and_then(NopLayer) + .and_then(NopLayer) + .with_subscriber(NopSubscriber); + assert!(Subscriber::downcast_ref::(&s).is_some()); + } + + #[test] + fn downcasts_to_layer() { + let s = NopLayer + .and_then(NopLayer) + .and_then(NopLayer2) + .with_subscriber(NopSubscriber); + assert!(Subscriber::downcast_ref::(&s).is_some()); + assert!(Subscriber::downcast_ref::(&s).is_some()); + } +} diff --git a/tracing-subscriber/src/lib.rs b/tracing-subscriber/src/lib.rs index 760d1047dc..d03c8b211d 100644 --- a/tracing-subscriber/src/lib.rs +++ b/tracing-subscriber/src/lib.rs @@ -1,19 +1,10 @@ //! Utilities and helpers for implementing and composing subscribers. +use tracing_core::span::Id; -extern crate tracing; -pub use tracing::{Event, Id}; - -// mod compose; -// pub use compose::Composed; - -// pub mod filter; -// pub mod observe; -// pub mod registry; - -// pub use filter::{Filter, FilterExt}; -// pub use observe::{Observe, ObserveExt}; -// pub use registry::{RegisterSpan, SpanRef}; +pub mod layer; +pub mod prelude; +pub use layer::Layer; use std::{cell::RefCell, default::Default, thread}; /// Tracks the currently executing span on a per-thread basis. @@ -55,3 +46,10 @@ impl Default for CurrentSpanPerThread { Self::new() } } + +mod sealed { + pub struct SealedTy { + _p: (), + } + pub trait Sealed {} +} diff --git a/tracing-subscriber/src/prelude.rs b/tracing-subscriber/src/prelude.rs new file mode 100644 index 0000000000..7a38efeb4a --- /dev/null +++ b/tracing-subscriber/src/prelude.rs @@ -0,0 +1,3 @@ +pub use crate::layer::{ + Layer as __tracing_subscriber_Layer, SubscriberExt as __tracing_subscriber_SubscriberExt, +};