From b8dfbe8c59a4fb57eded403f17e855b545918f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Sun, 5 Jan 2025 13:39:53 -0800 Subject: [PATCH] subscriber: enable TestWriter to write to stderr It can be useful to have a TestWriter that does not log to stdout but stderr instead. For example, that allows for potentially easier filtering of tracing output (because the remaining output of, say, cargo test goes to stdout) or to mirror behavior of env_logger, which by default logs to stderr. Introduce the TestWriter::with_stderr() constructor to enable such usage. The default is left unchanged. --- tracing-subscriber/src/fmt/writer.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tracing-subscriber/src/fmt/writer.rs b/tracing-subscriber/src/fmt/writer.rs index 165767cf2..a5aa9f991 100644 --- a/tracing-subscriber/src/fmt/writer.rs +++ b/tracing-subscriber/src/fmt/writer.rs @@ -495,8 +495,10 @@ pub struct MutexGuardWriter<'a, W>(MutexGuard<'a, W>); /// /// `TestWriter` is used by [`fmt::Collector`] or [`fmt::Subscriber`] to enable capturing support. /// -/// `cargo test` can only capture output from the standard library's [`print!`] macro. See -/// [`libtest`'s output capturing][capturing] for more details about output capturing. +/// `cargo test` can only capture output from the standard library's [`print!`] and [`eprint!`] +/// macros. See [`libtest`'s output capturing][capturing] and +/// [rust-lang/rust#90785](https://github.com/rust-lang/rust/issues/90785) for more details about +/// output capturing. /// /// Writing to [`io::stdout`] and [`io::stderr`] produces the same results as using /// [`libtest`'s `--nocapture` option][nocapture] which may make the results look unreadable. @@ -510,7 +512,9 @@ pub struct MutexGuardWriter<'a, W>(MutexGuard<'a, W>); /// [`print!`]: std::print! #[derive(Default, Debug)] pub struct TestWriter { - _p: (), + /// Whether or not to use `stderr` instead of the default `stdout` as + /// the underlying stream to write to. + use_stderr: bool, } /// A writer that erases the specific [`io::Write`] and [`MakeWriter`] types being used. @@ -670,12 +674,23 @@ impl TestWriter { pub fn new() -> Self { Self::default() } + + /// Returns a new `TestWriter` that writes to `stderr` instead of `stdout`. + pub fn with_stderr() -> Self { + Self { + use_stderr: true, + } + } } impl io::Write for TestWriter { fn write(&mut self, buf: &[u8]) -> io::Result { let out_str = String::from_utf8_lossy(buf); - print!("{}", out_str); + if self.use_stderr { + eprint!("{}", out_str) + } else { + print!("{}", out_str) + } Ok(buf.len()) }