Tracing conditionally to stdout

56 Views Asked by At

I have Rust tracing_subscriber configured to write all log messages to stderr by default (along with some customizations as you can see below). This is what I normally want. Here's the setup code:

use std::fmt;
use std::io;

use tracing::{Event, Level, Subscriber};
use tracing_subscriber::fmt::format;
use tracing_subscriber::{
    fmt::{FmtContext, FormatEvent, FormatFields},
    registry::LookupSpan,
};

/// A [tracing_subscriber] event formatter that suppresses everything but the
/// log message.
///
/// Level/target are displayed for non-INFO messages.
struct BareFormatter;

impl<S, N> FormatEvent<S, N> for BareFormatter
where
    S: Subscriber + for<'a> LookupSpan<'a>,
    N: for<'a> FormatFields<'a> + 'static,
{
    fn format_event(
        &self,
        ctx: &FmtContext<'_, S, N>,
        mut writer: format::Writer<'_>,
        event: &Event<'_>,
    ) -> fmt::Result {
        let metadata = event.metadata();
        if metadata.level() != &Level::INFO {
            write!(&mut writer, "{} {}: ", metadata.level(), metadata.target())?;
        }
        ctx.field_format().format_fields(writer.by_ref(), event)?;
        writeln!(writer)
    }
}

pub fn setup_logging(verbose: bool) {
    let env_filter = if verbose {
        "nixci=debug,nix_rs=debug"
    } else {
        "nixci=info,nix_rs=info"
    };
    let builder = tracing_subscriber::fmt()
        .with_writer(io::stderr)
        .with_max_level(Level::INFO)
        .with_env_filter(env_filter);

    if !verbose {
        builder.event_format(BareFormatter).init();
    } else {
        builder.init()
    }
}

Now, I want, in a few places, to send these logs to stdout instead, using something like:

tracing::info!(to: "stdout", "This message goes to stdout");

How can I modify setup_logging to achieve this?

0

There are 0 best solutions below