diff --git a/tracing-subscriber/src/fmt/fmt_layer.rs b/tracing-subscriber/src/fmt/fmt_layer.rs index d3cb8c1ed5..c2efaa73d8 100644 --- a/tracing-subscriber/src/fmt/fmt_layer.rs +++ b/tracing-subscriber/src/fmt/fmt_layer.rs @@ -71,6 +71,7 @@ pub struct Layer< fmt_fields: N, fmt_event: E, fmt_span: format::FmtSpanConfig, + needs_span_fields: bool, is_ansi: bool, log_internal_errors: bool, _inner: PhantomData, @@ -120,6 +121,7 @@ where fmt_fields: self.fmt_fields, fmt_event: e, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -150,6 +152,7 @@ where fmt_fields: self.fmt_fields, fmt_event: f(self.fmt_event), fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -184,6 +187,7 @@ impl Layer { fmt_fields: self.fmt_fields, fmt_event: self.fmt_event, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, make_writer, @@ -268,6 +272,7 @@ impl Layer { fmt_fields: self.fmt_fields, fmt_event: self.fmt_event, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, make_writer: TestWriter::default(), @@ -364,6 +369,7 @@ impl Layer { fmt_fields: self.fmt_fields, fmt_event: self.fmt_event, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, make_writer: f(self.make_writer), @@ -395,6 +401,7 @@ where fmt_event: self.fmt_event.with_timer(timer), fmt_fields: self.fmt_fields, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -408,6 +415,7 @@ where fmt_event: self.fmt_event.without_time(), fmt_fields: self.fmt_fields, fmt_span: self.fmt_span.without_time(), + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -537,6 +545,7 @@ where fmt_event: self.fmt_event.compact(), fmt_fields: self.fmt_fields, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -552,6 +561,7 @@ where fmt_event: self.fmt_event.pretty(), fmt_fields: format::Pretty::default(), fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -582,6 +592,7 @@ where fmt_event: self.fmt_event.json(), fmt_fields: format::JsonFields::new(), fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, // always disable ANSI escapes in JSON mode! is_ansi: false, @@ -601,8 +612,9 @@ impl Layer, W> { self, flatten_event: bool, ) -> Layer, W> { + let fmt_event = self.fmt_event.flatten_event(flatten_event); Layer { - fmt_event: self.fmt_event.flatten_event(flatten_event), + fmt_event, fmt_fields: format::JsonFields::new(), ..self } @@ -616,9 +628,13 @@ impl Layer, W> { self, display_current_span: bool, ) -> Layer, W> { + let fmt_event = self.fmt_event.with_current_span(display_current_span); + let needs_span_fields = + fmt_event.format.display_current_span || fmt_event.format.display_span_list; Layer { - fmt_event: self.fmt_event.with_current_span(display_current_span), + fmt_event, fmt_fields: format::JsonFields::new(), + needs_span_fields, ..self } } @@ -631,9 +647,13 @@ impl Layer, W> { self, display_span_list: bool, ) -> Layer, W> { + let fmt_event = self.fmt_event.with_span_list(display_span_list); + let needs_span_fields = + fmt_event.format.display_current_span || fmt_event.format.display_span_list; Layer { - fmt_event: self.fmt_event.with_span_list(display_span_list), + fmt_event, fmt_fields: format::JsonFields::new(), + needs_span_fields, ..self } } @@ -650,6 +670,7 @@ impl Layer { fmt_event: self.fmt_event, fmt_fields, fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -681,6 +702,7 @@ impl Layer { fmt_event: self.fmt_event, fmt_fields: f(self.fmt_fields), fmt_span: self.fmt_span, + needs_span_fields: self.needs_span_fields, make_writer: self.make_writer, is_ansi: self.is_ansi, log_internal_errors: self.log_internal_errors, @@ -699,6 +721,7 @@ impl Default for Layer { fmt_fields: format::DefaultFields::default(), fmt_event: format::Format::default(), fmt_span: format::FmtSpanConfig::default(), + needs_span_fields: true, make_writer: io::stdout, is_ansi: ansi, log_internal_errors: false, @@ -812,7 +835,7 @@ 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() { + if self.needs_span_fields && extensions.get_mut::>().is_none() { let mut fields = FormattedFields::::new(String::new()); if self .fmt_fields @@ -846,6 +869,10 @@ where } fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { + if !self.needs_span_fields { + return; + } + 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::>() { diff --git a/tracing-subscriber/src/fmt/format/mod.rs b/tracing-subscriber/src/fmt/format/mod.rs index 80612e1ec2..6573d51581 100644 --- a/tracing-subscriber/src/fmt/format/mod.rs +++ b/tracing-subscriber/src/fmt/format/mod.rs @@ -399,7 +399,7 @@ pub struct Full; /// intended for use in development. #[derive(Debug, Clone)] pub struct Format { - format: F, + pub(crate) format: F, pub(crate) timer: T, pub(crate) ansi: Option, pub(crate) display_timestamp: bool, @@ -2117,6 +2117,47 @@ pub(super) mod test { } } + mod json { + use core::cell::Cell; + + use super::*; + + struct CountDebugCalls(Cell); + + impl fmt::Debug for CountDebugCalls { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let value = self.0.get() + 1; + self.0.set(value); + write!(f, "CountDebugCalls({value})") + } + } + + #[test] + fn does_not_record_span_fields() { + let make_writer = MockMakeWriter::default(); + let subscriber = crate::fmt::Subscriber::builder() + .json() + .with_current_span(false) + .with_span_list(false) + .with_writer(make_writer.clone()) + .with_timer(MockTime); + let _default = set_default(&subscriber.into()); + + let count_debug_calls = CountDebugCalls(Cell::default()); + + let span = tracing::info_span!("a span", fields = ?count_debug_calls); + let _guard = span.enter(); + tracing::info!("an event"); + + let result = make_writer.get_string(); + assert_eq!( + result.trim(), + r#"{"timestamp":"fake time","level":"INFO","fields":{"message":"an event"},"target":"tracing_subscriber::fmt::format::test::json"}"# + ); + assert_eq!(count_debug_calls.0.get(), 0); + } + } + #[test] fn format_nanos() { fn fmt(t: u64) -> String {