From 54eff3409d34d7fce10af709a9618d5800f1b12d Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Thu, 28 Jan 2021 18:17:04 +0100 Subject: [PATCH] subscriber: add sample implementation of `FormatEvent` (#1189) * Add sample implementation of `FormatEvent` The docs previously didn't provide much help implementing `FormatEvent`. Especially getting access to fields on spans could be tricky unless the user was aware of `FormattedFields`. This updates the docs with a basic, but working, example. * Apply suggestions from code review Co-authored-by: Eliza Weisman * Add comment explaining what `FormattedFields` is * Expand docs a bit * Fix formatting Co-authored-by: Eliza Weisman --- tracing-subscriber/src/fmt/format/mod.rs | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index 9020a6390f..c00825ac06 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -45,6 +45,74 @@ use fmt::{Debug, Display}; /// This trait is already implemented for function pointers with the same /// signature as `format_event`. /// +/// # Examples +/// +/// ```rust +/// use std::fmt::{self, Write}; +/// use tracing_core::{Subscriber, Event}; +/// use tracing_subscriber::fmt::{FormatEvent, FormatFields, FmtContext, FormattedFields}; +/// use tracing_subscriber::registry::LookupSpan; +/// +/// struct MyFormatter; +/// +/// impl FormatEvent for MyFormatter +/// where +/// S: Subscriber + for<'a> LookupSpan<'a>, +/// N: for<'a> FormatFields<'a> + 'static, +/// { +/// fn format_event( +/// &self, +/// ctx: &FmtContext<'_, S, N>, +/// writer: &mut dyn fmt::Write, +/// event: &Event<'_>, +/// ) -> fmt::Result { +/// // Write level and target +/// let level = *event.metadata().level(); +/// let target = event.metadata().target(); +/// write!( +/// writer, +/// "{} {}: ", +/// level, +/// target, +/// )?; +/// +/// // Write spans and fields of each span +/// ctx.visit_spans(|span| { +/// write!(writer, "{}", span.name())?; +/// +/// let ext = span.extensions(); +/// +/// // `FormattedFields` is a 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 fields = &ext +/// .get::>() +/// .expect("will never be `None`"); +/// +/// if !fields.is_empty() { +/// write!(writer, "{{{}}}", fields)?; +/// } +/// write!(writer, ": ")?; +/// +/// Ok(()) +/// })?; +/// +/// // Write fields on the event +/// ctx.field_format().format_fields(writer, event)?; +/// +/// writeln!(writer) +/// } +/// } +/// ``` +/// +/// This formatter will print events like this: +/// +/// ```text +/// DEBUG yak_shaving::shaver: some-span{field-on-span=foo}: started shaving yak +/// ``` +/// /// [`fmt::Subscriber`]: ../struct.Subscriber.html /// [`fmt::Layer`]: ../struct.Layer.html pub trait FormatEvent