Skip to content

Commit

Permalink
subscriber: enable TestWriter to write to stderr
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
d-e-s-o committed Jan 5, 2025
1 parent b02a700 commit 85c3826
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions tracing-subscriber/src/fmt/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@ 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] 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.
Expand All @@ -510,7 +510,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.
Expand Down Expand Up @@ -670,12 +672,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<usize> {
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())
}

Expand Down

0 comments on commit 85c3826

Please sign in to comment.