diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index c6c7bfa95b..6dd4222ccc 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -35,15 +35,55 @@ use fmt::{Debug, Display}; /// A type that can format a tracing [`Event`] to a [`Writer`]. /// -/// `FormatEvent` is primarily used in the context of [`fmt::Collector`] or [`fmt::Subscriber`]. -/// Each time an event is dispatched to [`fmt::Collector`] or [`fmt::Subscriber`], -/// the collector or subscriber forwards it to its associated `FormatEvent` to emit a log message. +/// `FormatEvent` is primarily used in the context of [`fmt::Collector`] or +/// [`fmt::Subscriber`]. Each time an event is dispatched to [`fmt::Collector`] +/// or [`fmt::Subscriber`], the collector or subscriber forwards it to its +/// associated `FormatEvent` to emit a log message. /// /// This trait is already implemented for function pointers with the same /// signature as `format_event`. /// +/// # Arguments +/// +/// The following arguments are passed to `FormatEvent::format_event`: +/// +/// * A [`FmtContext`]. This is an extension of the [`subscribe::Context`] type, +/// which can be used for accessing stored information such as the current +/// span context an event occurred in. +/// +/// In addition, [`FmtContext`] exposes access to the [`FormatFields`] +/// implementation that the subscriber was configured to use via the +/// [`FmtContext::field_format`] method. This can be used when the +/// [`FormatEvent`] implementation needs to format the event's fields. +/// +/// For convenience, [`FmtContext`] also [implements `FormatFields`], +/// forwarding to the configured [`FormatFields`] type. +/// +/// * A [`Writer`] to which the formatted representation of the event is +/// written. This type implements the [`std::fmt::Write`] trait, and therefore +/// can be used with the [`std::write!`] and [`std::writeln!`] macros, as well +/// as calling [`std::fmt::Write`] methods directly. +/// +/// The [`Writer`] type also implements additional methods that provide +/// information about how the event should be formatted. The +/// [`Writer::has_ansi_escapes`] method indicates whether [ANSI terminal +/// escape codes] are supported by the underlying I/O writer that the event +/// will be written to. If this returns `true`, the formatter is permitted to +/// use ANSI escape codes to add colors and other text formatting to its +/// output. If it returns `false`, the event will be written to an output that +/// does not support ANSI escape codes (such as a log file), and they should +/// not be emitted. +/// +/// Crates like [`ansi_term`] and [`owo-colors`] can be used to add ANSI +/// escape codes to formatted output. +/// +/// * The actual [`Event`] to be formatted. +/// /// # Examples /// +/// This example re-implements a simiplified version of this crate's [default +/// formatter]: +/// /// ```rust /// use std::fmt; /// use tracing_core::{Collect, Event}; @@ -67,31 +107,25 @@ use fmt::{Debug, Display}; /// mut writer: format::Writer<'_>, /// event: &Event<'_>, /// ) -> fmt::Result { -/// // Write level and target -/// let level = *event.metadata().level(); -/// let target = event.metadata().target(); -/// write!( -/// writer, -/// "{} {}: ", -/// level, -/// target, -/// )?; +/// // Format values from the event's's metadata: +/// let metadata = event.metadata(); +/// write!(&mut writer, "{} {}: ", metadata.level(), metadata.target())?; /// -/// // Write spans and fields of each span +/// // Format all the spans in the event's span context. /// ctx.visit_spans(|span| { /// write!(writer, "{}", span.name())?; /// -/// let ext = span.extensions(); -/// -/// // `FormattedFields` is a a formatted representation of the span's +/// // `FormattedFields` is a formatted representation of the span's /// // fields, which is stored in its extensions by the `fmt` layer's /// // `new_span` method. The fields will have been formatted /// // by the same field formatter that's provided to the event /// // formatter in the `FmtContext`. +/// let ext = span.extensions(); /// let fields = &ext /// .get::>() /// .expect("will never be `None`"); /// +/// // Skip formatting the fields if the span had no fields. /// if !fields.is_empty() { /// write!(writer, "{{{}}}", fields)?; /// } @@ -106,6 +140,13 @@ use fmt::{Debug, Display}; /// writeln!(writer) /// } /// } +/// +/// let _subscriber = tracing_subscriber::fmt() +/// .event_format(MyFormatter) +/// .init(); +/// +/// let _span = tracing::info_span!("my_span", answer = 42).entered(); +/// tracing::info!(question = "life, the universe, and everything", "hello world"); /// ``` /// /// This formatter will print events like this: @@ -116,7 +157,14 @@ use fmt::{Debug, Display}; /// /// [`fmt::Collector`]: super::Collector /// [`fmt::Subscriber`]: super::Subscriber +/// [`subscribe::Context`]: crate::subscribe::Context /// [`Event`]: tracing::Event +/// [implements `FormatFields`]: super::FmtContext#impl-FormatFields<'writer> +/// [ANSI terminal escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code +/// [`Writer::has_ansi_escapes`]: Writer::has_ansi_escapes +/// [`ansi_term`]: https://crates.io/crates/ansi_term +/// [`owo-colors`]: https://crates.io/crates/owo-colors +/// [default formatter]: Full pub trait FormatEvent where C: Collect + for<'a> LookupSpan<'a>, @@ -373,14 +421,16 @@ impl<'writer> Writer<'writer> { self.writer.write_fmt(args) } - /// Returns `true` if ANSI escape codes may be used to add colors + /// Returns `true` if [ANSI escape codes] may be used to add colors /// and other formatting when writing to this `Writer`. /// /// If this returns `false`, formatters should not emit ANSI escape codes. + /// + /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code pub fn has_ansi_escapes(&self) -> bool { self.is_ansi } - + pub(in crate::fmt::format) fn bold(&self) -> Style { #[cfg(feature = "ansi")] { diff --git a/tracing-subscriber/src/fmt/mod.rs b/tracing-subscriber/src/fmt/mod.rs index 3ff1f318a9..2d910f5d16 100644 --- a/tracing-subscriber/src/fmt/mod.rs +++ b/tracing-subscriber/src/fmt/mod.rs @@ -1,13 +1,13 @@ //! A Collector for formatting and logging `tracing` data. //! -//! ## Overview +//! # Overview //! //! [`tracing`] is a framework for instrumenting Rust programs with context-aware, //! structured, event-based diagnostic information. This crate provides an //! implementation of the [`Collect`] trait that records `tracing`'s `Event`s //! and `Span`s by formatting them as text and logging them to stdout. //! -//! ## Usage +//! # Usage //! //! First, add this to your `Cargo.toml` file: //! @@ -43,12 +43,12 @@ //! **Note**: This should **not** be called by libraries. Libraries should use //! [`tracing`] to publish `tracing` `Event`s. //! -//! ## Configuration +//! # Configuration //! //! You can configure a collector instead of using the defaults with //! the following functions: //! -//! ### Collector +//! ## Collector //! //! The [`FmtCollector`] formats and records `tracing` events as line-oriented logs. //! You can create one by calling: @@ -62,7 +62,7 @@ //! The configuration methods for [`FmtCollector`] can be found in //! [`fmtBuilder`]. //! -//! ### Formatters +//! ## Formatters //! //! The output format used by the subscriber and collector in this module is //! represented by implementing the [`FormatEvent`] trait, and can be @@ -223,7 +223,44 @@ //! {"timestamp":"Oct 24 13:00:00.875","level":"INFO","fields":{"message":"yak shaving completed","all_yaks_shaved":false},"target":"fmt_json"} //! //! -//! ### Filters +//! ### Customizing Formatters +//! +//! The formatting of log lines for spans and events is controlled by two +//! traits, [`FormatEvent`] and [`FormatFields`]. The [`FormatEvent`] trait +//! determines the overall formatting of the log line, such as what information +//! from the event's metadata and span context is included and in what order. +//! The [`FormatFields`] trait determines how fields — both the event's +//! fields and fields on spans — are formatted. +//! +//! The [`fmt::format`] module provides several types which implement these traits, +//! many of which expose additional configuration options to customize their +//! output. The [`format::Format`] type implements common configuration used by +//! all the formatters provided in this crate, and can be used as a builder to +//! set specific formatting settings. For example: +//! +//! ``` +//! use tracing_subscriber::fmt; +//! +//! // Configure a custom event formatter +//! let format = fmt::format() +//! .with_level(false) // don't include levels in formatted output +//! .with_target(false) // don't include targets +//! .with_thread_ids(true) // include the thread ID of the current thread +//! .with_thread_names(true) // include the name of the current thread +//! .compact(); // use the `Compact` formatting style. +//! +//! // Create a `fmt` collector that uses our custom event format, and set it +//! // as the default. +//! tracing_subscriber::fmt() +//! .event_format(format) +//! .init(); +//! ``` +//! +//! However, if a specific output format is needed, other crates can +//! also implement [`FormatEvent`] and [`FormatFields`]. See those traits' +//! documentation for details on how to implement them. +//! +//! ## Filters //! //! If you want to filter the `tracing` `Events` based on environment //! variables, you can use the [`EnvFilter`] as follows: @@ -257,7 +294,7 @@ //! // collector multiple times //! ``` //! -//! ### Composing Subscribers +//! ## Composing Subscribers //! //! Composing an [`EnvFilter`] `Subscribe` and a [format `Subscribe`](super::fmt::Subscriber): //! @@ -283,9 +320,9 @@ //! [`filter`]: super::filter //! [`fmtBuilder`]: CollectorBuilder //! [`FmtCollector`]: Collector -//! [`Collect`]: -//! https://docs.rs/tracing/latest/tracing/trait.Collect.html +//! [`Collect`]: https://docs.rs/tracing/latest/tracing/trait.Collect.html //! [`tracing`]: https://crates.io/crates/tracing +//! [`fmt::format`]: mod@crate::fmt::format use std::{any::TypeId, error::Error, io, ptr::NonNull}; use tracing_core::{collect::Interest, span, Event, Metadata}; diff --git a/tracing-subscriber/src/lib.rs b/tracing-subscriber/src/lib.rs index c71e2e6d07..490dc92b0f 100644 --- a/tracing-subscriber/src/lib.rs +++ b/tracing-subscriber/src/lib.rs @@ -43,7 +43,7 @@ //! //! - [`tracing-log`]: Enables better formatting for events emitted by `log` //! macros in the `fmt` subscriber. Enabled by default. -//! - [`time`]: Enables support for using the [`time` crate] for timestamp +//! - [`time`][`time` crate]: Enables support for using the [`time` crate] for timestamp //! formatting in the `fmt` subscriber. //! - [`smallvec`]: Causes the `EnvFilter` type to use the `smallvec` crate (rather //! than `Vec`) as a performance optimization. Enabled by default.