rework log verbosity (-vvv) (#11758)

Reworks how log verbosity flags work.

* `<no argument>` is the same, equivalent to `RUST_LOG=off`
* `-v` is the same, equivalent to `RUST_LOG=uv=debug`
* `-vv` is now equivalent to `RUST_LOG=uv=trace` (previously it only
enabled more log message context)
* `-vvv` is now equivalent to `RUST_LOG=trace` (previously it was
equivalent to `-vv`)

The "more context" that `-vv` had has been moved to an orthogonal
setting via an environment variable. Setting `UV_LOG_CONTEXT=1` will add
the extra context that `-vv` did.

In the future we may make these more granular as we try to use
`info!/warn!` more.

Fixes #1569
This commit is contained in:
Aria Desires 2025-02-28 18:49:27 -05:00 committed by GitHub
parent dc39d6622b
commit 7acdbf6414
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 47 deletions

View file

@ -553,6 +553,11 @@ impl EnvVars {
/// for more.
pub const RUST_LOG: &'static str = "RUST_LOG";
/// Add additional context and structure to log messages.
///
/// If logging is not enabled, e.g., with `RUST_LOG` or `-v`, this has no effect.
pub const UV_LOG_CONTEXT: &'static str = "UV_LOG_CONTEXT";
/// Use to set the stack size used by uv.
///
/// The value is in bytes, and the default is typically 2MB (2097152).

View file

@ -278,9 +278,10 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
let duration_layer = None::<tracing_subscriber::layer::Identity>;
logging::setup_logging(
match globals.verbose {
0 => logging::Level::Default,
1 => logging::Level::Verbose,
2.. => logging::Level::ExtraVerbose,
0 => logging::Level::Off,
1 => logging::Level::DebugUv,
2 => logging::Level::TraceUv,
3.. => logging::Level::TraceAll,
},
duration_layer,
globals.color,

View file

@ -20,18 +20,15 @@ use tracing_tree::time::Uptime;
use tracing_tree::HierarchicalLayer;
use uv_cli::ColorChoice;
#[cfg(feature = "tracing-durations-export")]
use uv_static::EnvVars;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Level {
/// Suppress all tracing output by default (overridable by `RUST_LOG`).
#[default]
Default,
/// Show debug messages by default (overridable by `RUST_LOG`).
Verbose,
/// Show messages in a hierarchical span tree. By default, debug messages are shown (overridable by `RUST_LOG`).
ExtraVerbose,
Off,
DebugUv,
TraceUv,
TraceAll,
}
struct UvFormat {
@ -120,15 +117,24 @@ pub(crate) fn setup_logging(
durations: impl Layer<Registry> + Send + Sync,
color: ColorChoice,
) -> anyhow::Result<()> {
// We use directives here to ensure `RUST_LOG` can override them
let default_directive = match level {
Level::Default => {
// Show nothing, but allow `RUST_LOG` to override.
Level::Off => {
// Show nothing
tracing::level_filters::LevelFilter::OFF.into()
}
Level::Verbose | Level::ExtraVerbose => {
// Show `DEBUG` messages from the CLI crate, but allow `RUST_LOG` to override.
Level::DebugUv => {
// Show `DEBUG` messages from the CLI crate (and ERROR/WARN/INFO)
Directive::from_str("uv=debug").unwrap()
}
Level::TraceUv => {
// Show `TRACE` messages from the CLI crate (and ERROR/WARN/INFO/DEBUG)
Directive::from_str("uv=trace").unwrap()
}
Level::TraceAll => {
// Show all `TRACE` messages (and ERROR/WARN/INFO/DEBUG)
Directive::from_str("trace").unwrap()
}
};
// Only record our own spans.
@ -160,40 +166,38 @@ pub(crate) fn setup_logging(
};
let writer = std::sync::Mutex::new(anstream::AutoStream::new(std::io::stderr(), color_choice));
match level {
Level::Default | Level::Verbose => {
// Regardless of the tracing level, show messages without any adornment.
let format = UvFormat {
display_timestamp: false,
display_level: true,
show_spans: false,
};
let detailed_logging = std::env::var(EnvVars::UV_LOG_CONTEXT).is_ok();
if detailed_logging {
// Regardless of the tracing level, include the uptime and target for each message.
tracing_subscriber::registry()
.with(durations_layer)
.with(
HierarchicalLayer::default()
.with_targets(true)
.with_timer(Uptime::default())
.with_writer(writer)
.with_ansi(ansi)
.with_filter(filter),
)
.init();
} else {
// Regardless of the tracing level, show messages without any adornment.
let format = UvFormat {
display_timestamp: false,
display_level: true,
show_spans: false,
};
tracing_subscriber::registry()
.with(durations_layer)
.with(
tracing_subscriber::fmt::layer()
.event_format(format)
.with_writer(writer)
.with_ansi(ansi)
.with_filter(filter),
)
.init();
}
Level::ExtraVerbose => {
// Regardless of the tracing level, include the uptime and target for each message.
tracing_subscriber::registry()
.with(durations_layer)
.with(
HierarchicalLayer::default()
.with_targets(true)
.with_timer(Uptime::default())
.with_writer(writer)
.with_ansi(ansi)
.with_filter(filter),
)
.init();
}
tracing_subscriber::registry()
.with(durations_layer)
.with(
tracing_subscriber::fmt::layer()
.event_format(format)
.with_writer(writer)
.with_ansi(ansi)
.with_filter(filter),
)
.init();
}
Ok(())