Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subscriber: add set_span_events to fmt::Subscriber #2962

Merged
merged 3 commits into from
May 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
69 changes: 69 additions & 0 deletions tracing-subscriber/src/fmt/fmt_subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,27 @@ impl<C, N, E, W> Subscriber<C, N, E, W> {
self.is_ansi = ansi;
}

/// Modifies how synthesized events are emitted at points in the [span
/// lifecycle][lifecycle].
///
/// See [`Self::with_span_events`] for documentation on the [`FmtSpan`]
///
/// This method is primarily expected to be used with the
/// [`reload::Handle::modify`](crate::reload::Handle::modify) method
///
/// Note that using this method modifies the span configuration instantly and does not take into
/// account any current spans. If the previous configuration was set to capture
/// `FmtSpan::ALL`, for example, using this method to change to `FmtSpan::NONE` will cause an
/// exit event for currently entered events not to be formatted
///
/// [lifecycle]: mod@tracing::span#the-span-lifecycle
pub fn set_span_events(&mut self, kind: FmtSpan) {
self.fmt_span = format::FmtSpanConfig {
kind,
fmt_timing: self.fmt_span.fmt_timing,
}
}

/// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in
/// unit tests.
///
Expand Down Expand Up @@ -1590,4 +1611,52 @@ mod test {
// dropping `_saved_no_color` will restore the previous value of
// `NO_COLOR`.
}

// Validates that span event configuration can be modified with a reload handle
#[test]
fn modify_span_events() {
let make_writer = MockMakeWriter::default();

let inner_subscriber = fmt::Subscriber::default()
.with_writer(make_writer.clone())
.with_level(false)
.with_ansi(false)
.with_timer(MockTime)
.with_span_events(FmtSpan::ACTIVE);

let (reloadable_subscriber, reload_handle) =
crate::reload::Subscriber::new(inner_subscriber);
let reload = reloadable_subscriber.with_collector(Registry::default());

with_default(reload, || {
{
let span1 = tracing::info_span!("span1", x = 42);
let _e = span1.enter();
}

let _ = reload_handle.modify(|s| s.set_span_events(FmtSpan::NONE));

// this span should not be logged at all!
{
let span2 = tracing::info_span!("span2", x = 100);
let _e = span2.enter();
}

{
let span3 = tracing::info_span!("span3", x = 42);
let _e = span3.enter();

// The span config was modified after span3 was already entered.
// We should only see an exit
let _ = reload_handle.modify(|s| s.set_span_events(FmtSpan::ACTIVE));
}
});
let actual = sanitize_timings(make_writer.get_string());
assert_eq!(
"fake time span1{x=42}: tracing_subscriber::fmt::fmt_subscriber::test: enter\n\
fake time span1{x=42}: tracing_subscriber::fmt::fmt_subscriber::test: exit\n\
fake time span3{x=42}: tracing_subscriber::fmt::fmt_subscriber::test: exit\n",
actual.as_str()
);
}
}