From 02b3de3688866cde6c5227cb8459de5402b737dd Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 13 Jan 2021 22:25:54 +0100 Subject: [PATCH 1/5] 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. --- tracing-subscriber/src/fmt/format/mod.rs | 61 ++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index e223aa7bc7..a4d7e0e287 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -46,6 +46,67 @@ use fmt::{Debug, Display}; /// This trait is already implemented for function pointers with the same /// signature as `format_event`. /// +/// # Example implementation +/// +/// ```rust +/// use std::fmt::{self, Write}; +/// use tracing_core::{Collect, Event}; +/// use tracing_subscriber::fmt::{FormatEvent, FormatFields, FmtContext, FormattedFields}; +/// use tracing_subscriber::registry::LookupSpan; +/// +/// struct MyFormatter; +/// +/// impl FormatEvent for MyFormatter +/// where +/// S: Collect + 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(); +/// 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) +/// } +/// } +/// ``` +/// +/// That will result in events printed like so: +/// +/// ```text +/// DEBUG yak_shaving::shaver: some-span{field-on-span=foo}: started shaving yak +/// ``` +/// /// [`fmt::Collector`]: super::Collector /// [`fmt::Subscriber`]: super::Subscriber pub trait FormatEvent From 53ae77231b8d5dad4cce9be09ea4a872a137d70c Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 27 Jan 2021 22:57:36 +0100 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Eliza Weisman --- tracing-subscriber/src/fmt/format/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index a4d7e0e287..9b6cf85d63 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -46,7 +46,7 @@ use fmt::{Debug, Display}; /// This trait is already implemented for function pointers with the same /// signature as `format_event`. /// -/// # Example implementation +/// # Examples /// /// ```rust /// use std::fmt::{self, Write}; @@ -101,7 +101,7 @@ use fmt::{Debug, Display}; /// } /// ``` /// -/// That will result in events printed like so: +/// This formatter will print events like this: /// /// ```text /// DEBUG yak_shaving::shaver: some-span{field-on-span=foo}: started shaving yak From 81d3d774fac21f38269f9541a3a0a833bb41b286 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 27 Jan 2021 23:01:26 +0100 Subject: [PATCH 3/5] Add comment explaining what `FormattedFields` is --- tracing-subscriber/src/fmt/format/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index 9b6cf85d63..b2761e991e 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -82,9 +82,13 @@ use fmt::{Debug, Display}; /// write!(writer, "{}", span.name())?; /// /// let ext = span.extensions(); +/// +/// // `FormattedFields` is a a formatted representation of the span's +/// // fields which are stored in its extensions /// let fields = &ext /// .get::>() /// .expect("will never be `None`"); +/// /// if !fields.is_empty() { /// write!(writer, "{{{}}}", fields)?; /// } From 559f124f6bc6cea493a24aacb1ce905ee9832c08 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 27 Jan 2021 23:32:25 +0100 Subject: [PATCH 4/5] Expand docs a bit --- tracing-subscriber/src/fmt/format/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index b2761e991e..7ed8c5531c 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -84,7 +84,10 @@ use fmt::{Debug, Display}; /// let ext = span.extensions(); /// /// // `FormattedFields` is a a formatted representation of the span's -/// // fields which are stored in its extensions +/// // 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`"); From c9f619a9df8f5b572c4521a693fa9dae3123d822 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Thu, 28 Jan 2021 10:28:05 +0100 Subject: [PATCH 5/5] Fix formatting --- tracing-subscriber/src/fmt/format/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index 7ed8c5531c..9c06c26ce2 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -86,7 +86,7 @@ use fmt::{Debug, Display}; /// // `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 +/// // by the same field formatter that's provided to the event /// // formatter in the `FmtContext`. /// let fields = &ext /// .get::>()