diff --git a/tracing-subscriber/src/fmt/fmt_subscriber.rs b/tracing-subscriber/src/fmt/fmt_subscriber.rs index eec4c3241..09ecefd4d 100644 --- a/tracing-subscriber/src/fmt/fmt_subscriber.rs +++ b/tracing-subscriber/src/fmt/fmt_subscriber.rs @@ -753,22 +753,22 @@ where /// the [`Extensions`][extensions] type-map. This means that when multiple /// formatters are in use, each can store its own formatted representation /// without conflicting. +/// The `ANSI` const parameter determines whether ANSI escape codes should be used +/// for formatting the fields (i.e. colors, font styles). /// /// [extensions]: crate::registry::Extensions #[derive(Default)] -pub struct FormattedFields { +pub struct FormattedFields { _format_fields: PhantomData, - was_ansi: bool, /// The formatted fields of a span. pub fields: String, } -impl FormattedFields { +impl FormattedFields { /// Returns a new `FormattedFields`. pub fn new(fields: String) -> Self { Self { fields, - was_ansi: false, _format_fields: PhantomData, } } @@ -778,27 +778,27 @@ impl FormattedFields { /// The returned [`format::Writer`] can be used with the /// [`FormatFields::format_fields`] method. pub fn as_writer(&mut self) -> format::Writer<'_> { - format::Writer::new(&mut self.fields).with_ansi(self.was_ansi) + format::Writer::new(&mut self.fields).with_ansi(ANSI) } } -impl fmt::Debug for FormattedFields { +impl fmt::Debug for FormattedFields { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("FormattedFields") .field("fields", &self.fields) .field("formatter", &format_args!("{}", std::any::type_name::())) - .field("was_ansi", &self.was_ansi) + .field("is_ansi", &format_args!("{}", ANSI)) .finish() } } -impl fmt::Display for FormattedFields { +impl fmt::Display for FormattedFields { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.fields, f) } } -impl Deref for FormattedFields { +impl Deref for FormattedFields { type Target = String; fn deref(&self) -> &Self::Target { &self.fields @@ -834,14 +834,29 @@ where let span = ctx.span(id).expect("Span not found, this is a bug"); let mut extensions = span.extensions_mut(); - if extensions.get_mut::>().is_none() { - let mut fields = FormattedFields::::new(String::new()); + if self.is_ansi { + if extensions.get_mut::>().is_none() { + let mut fields = FormattedFields::::new(String::new()); + if self + .fmt_fields + .format_fields(fields.as_writer().with_ansi(true), attrs) + .is_ok() + { + extensions.insert(fields); + } else { + eprintln!( + "[tracing-subscriber] Unable to format the following event, ignoring: {:?}", + attrs + ); + } + } + } else if extensions.get_mut::>().is_none() { + let mut fields = FormattedFields::::new(String::new()); if self .fmt_fields - .format_fields(fields.as_writer().with_ansi(self.is_ansi), attrs) + .format_fields(fields.as_writer().with_ansi(false), attrs) .is_ok() { - fields.was_ansi = self.is_ansi; extensions.insert(fields); } else { eprintln!( @@ -870,19 +885,35 @@ where fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, C>) { let span = ctx.span(id).expect("Span not found, this is a bug"); let mut extensions = span.extensions_mut(); - if let Some(fields) = extensions.get_mut::>() { - let _ = self.fmt_fields.add_fields(fields, values); - return; - } - let mut fields = FormattedFields::::new(String::new()); - if self - .fmt_fields - .format_fields(fields.as_writer().with_ansi(self.is_ansi), values) - .is_ok() - { - fields.was_ansi = self.is_ansi; - extensions.insert(fields); + if self.is_ansi { + if let Some(fields) = extensions.get_mut::>() { + let _ = self.fmt_fields.add_fields::(fields, values); + return; + } + + let mut fields = FormattedFields::::new(String::new()); + if self + .fmt_fields + .format_fields(fields.as_writer().with_ansi(true), values) + .is_ok() + { + extensions.insert(fields); + } + } else { + if let Some(fields) = extensions.get_mut::>() { + let _ = self.fmt_fields.add_fields::(fields, values); + return; + } + + let mut fields = FormattedFields::::new(String::new()); + if self + .fmt_fields + .format_fields(fields.as_writer().with_ansi(false), values) + .is_ok() + { + extensions.insert(fields); + } } } diff --git a/tracing-subscriber/src/fmt/format/json.rs b/tracing-subscriber/src/fmt/format/json.rs index c9f6eefc5..18a57ef8c 100644 --- a/tracing-subscriber/src/fmt/format/json.rs +++ b/tracing-subscriber/src/fmt/format/json.rs @@ -145,7 +145,7 @@ where let ext = self.0.extensions(); let data = ext - .get::>() + .get::>() .expect("Unable to find FormattedFields in extensions; this is a bug"); // TODO: let's _not_ do this, but this resolves @@ -358,9 +358,9 @@ impl<'a> FormatFields<'a> for JsonFields { /// By default, this appends a space to the current set of fields if it is /// non-empty, and then calls `self.format_fields`. If different behavior is /// required, the default implementation of this method can be overridden. - fn add_fields( + fn add_fields( &self, - current: &'a mut FormattedFields, + current: &'a mut FormattedFields, fields: &Record<'_>, ) -> fmt::Result { if current.is_empty() { diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index 6ea1891bc..0b5133e4e 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -152,7 +152,7 @@ use fmt::{Debug, Display}; /// // formatter in the `FmtContext`. /// let ext = span.extensions(); /// let fields = &ext -/// .get::>() +/// .get::>() /// .expect("will never be `None`"); /// /// // Skip formatting the fields if the span had no fields. @@ -240,9 +240,12 @@ pub trait FormatFields<'writer> { /// By default, this appends a space to the current set of fields if it is /// non-empty, and then calls `self.format_fields`. If different behavior is /// required, the default implementation of this method can be overridden. - fn add_fields( + /// + /// The `ANSI` const parameter determines whether ANSI escape codes should be used + /// for formatting the fields (i.e. colors and font styles). + fn add_fields( &self, - current: &'writer mut FormattedFields, + current: &'writer mut FormattedFields, fields: &span::Record<'_>, ) -> fmt::Result { if !current.fields.is_empty() { @@ -980,7 +983,13 @@ where seen = true; let ext = span.extensions(); - if let Some(fields) = &ext.get::>() { + if let Some(true) = self.ansi { + if let Some(fields) = &ext.get::>() { + if !fields.is_empty() { + write!(writer, "{}{}{}", bold.paint("{"), fields, bold.paint("}"))?; + } + } + }else if let Some(fields) = &ext.get::>() { if !fields.is_empty() { write!(writer, "{}{}{}", bold.paint("{"), fields, bold.paint("}"))?; } @@ -1108,7 +1117,13 @@ where for span in ctx.event_scope().into_iter().flat_map(Scope::from_root) { let exts = span.extensions(); - if let Some(fields) = exts.get::>() { + if let Some(true) = self.ansi { + if let Some(fields) = exts.get::>() { + if !fields.is_empty() { + write!(writer, " {}", dimmed.paint(&fields.fields))?; + } + } + } else if let Some(fields) = exts.get::>() { if !fields.is_empty() { write!(writer, " {}", dimmed.paint(&fields.fields))?; } diff --git a/tracing-subscriber/src/fmt/format/pretty.rs b/tracing-subscriber/src/fmt/format/pretty.rs index 1e17cf200..d135a8e74 100644 --- a/tracing-subscriber/src/fmt/format/pretty.rs +++ b/tracing-subscriber/src/fmt/format/pretty.rs @@ -309,11 +309,20 @@ where } let ext = span.extensions(); - let fields = &ext - .get::>() - .expect("Unable to find FormattedFields in extensions; this is a bug"); - if !fields.is_empty() { - write!(writer, " {} {}", dimmed.paint("with"), fields)?; + if let Some(true) = self.ansi { + let fields = &ext + .get::>() + .expect("Unable to find FormattedFields in extensions; this is a bug"); + if !fields.is_empty() { + write!(writer, " {} {}", dimmed.paint("with"), fields)?; + } + } else { + let fields = &ext + .get::>() + .expect("Unable to find FormattedFields in extensions; this is a bug"); + if !fields.is_empty() { + write!(writer, " {} {}", dimmed.paint("with"), fields)?; + } } writer.write_char('\n')?; } @@ -329,9 +338,9 @@ impl<'writer> FormatFields<'writer> for Pretty { v.finish() } - fn add_fields( + fn add_fields( &self, - current: &'writer mut FormattedFields, + current: &'writer mut FormattedFields, fields: &span::Record<'_>, ) -> fmt::Result { let empty = current.is_empty();