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

fmt::Subscriber NO_COLOR support #2647

Merged
merged 9 commits into from
Aug 17, 2023
64 changes: 62 additions & 2 deletions tracing-subscriber/src/fmt/fmt_subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
};
use format::{FmtSpan, TimingDisplay};
use std::{
any::TypeId, cell::RefCell, fmt, io, marker::PhantomData, ops::Deref, ptr::NonNull,
any::TypeId, cell::RefCell, env, fmt, io, marker::PhantomData, ops::Deref, ptr::NonNull,
time::Instant,
};
use tracing_core::{
Expand Down Expand Up @@ -680,12 +680,16 @@ impl<C, N, E, W> Subscriber<C, N, E, W> {

impl<C> Default for Subscriber<C> {
fn default() -> Self {
// only enable ANSI when the feature is enabled, and the NO_COLOR
// environment variable is unset or empty.
dmlary marked this conversation as resolved.
Show resolved Hide resolved
let ansi = cfg!(feature = "ansi") && env::var("NO_COLOR").map_or(true, |v| v.is_empty());
dmlary marked this conversation as resolved.
Show resolved Hide resolved

Subscriber {
fmt_fields: format::DefaultFields::default(),
fmt_event: format::Format::default(),
fmt_span: format::FmtSpanConfig::default(),
make_writer: io::stdout,
is_ansi: cfg!(feature = "ansi"),
is_ansi: ansi,
log_internal_errors: false,
_inner: PhantomData,
}
Expand Down Expand Up @@ -1505,4 +1509,60 @@ mod test {
actual.as_str()
);
}

// Because we need to modify an environment variable for these test cases,
// we do them all in a single test.
#[cfg(feature = "ansi")]
#[test]
fn subscriber_no_color() {
// save off the existing value of NO_COLOR
const NO_COLOR: &str = "NO_COLOR";
let saved_no_color = std::env::var(NO_COLOR);

let cases: Vec<(Option<&str>, bool)> = vec![
(Some("0"), false), // any non-empty value disables ansi
(Some("off"), false), // any non-empty value disables ansi
(Some("1"), false),
(Some(""), true), // empty value does not disable ansi
(None, true),
];

for (var, ansi) in cases {
if let Some(value) = var {
env::set_var(NO_COLOR, value);
} else {
env::remove_var(NO_COLOR);
}

let subscriber: Subscriber<()> = fmt::Subscriber::default();
assert_eq!(
subscriber.is_ansi, ansi,
"NO_COLOR={:?}; Subscriber::default().is_ansi should be {}",
var, ansi
);

// with_ansi should override any `NO_COLOR` value
let subscriber: Subscriber<()> = fmt::Subscriber::default().with_ansi(true);
assert!(
subscriber.is_ansi,
"NO_COLOR={:?}; Subscriber::default().with_ansi(true).is_ansi should be true",
var
);

// set_ansi should override any `NO_COLOR` value
let mut subscriber: Subscriber<()> = fmt::Subscriber::default();
subscriber.set_ansi(true);
assert!(
subscriber.is_ansi,
"NO_COLOR={:?}; subscriber.set_ansi(true); subscriber.is_ansi should be true",
var
);
}

if let Ok(value) = saved_no_color {
env::set_var(NO_COLOR, value);
} else {
env::remove_var(NO_COLOR);
}
dmlary marked this conversation as resolved.
Show resolved Hide resolved
}
}