Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,14 @@ to store the logs but not have them litter your display.

Display HTTP requests/responses in the logs.

### `MISE_LOG_VERBOSE_DEPS=1`

By default, `mise -v` (debug level) suppresses debug logs from noisy
third-party crates (`h2`, `hyper`, `reqwest`, `rustls`, etc.) that emit a line
per HTTP/2 frame or socket read. Set this to `1` to let those logs through at
debug level — or use `-vv`/`MISE_LOG_LEVEL=trace`, which always includes
them.

### `MISE_QUIET=1`

Equivalent to `MISE_LOG_LEVEL=warn`.
Expand Down
1 change: 1 addition & 0 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ pub static MISE_SELF_UPDATE_DISABLED_PATH: Lazy<Option<PathBuf>> = Lazy::new(||
)
});
pub static MISE_LOG_HTTP: Lazy<bool> = Lazy::new(|| var_is_true("MISE_LOG_HTTP"));
pub static MISE_LOG_VERBOSE_DEPS: Lazy<bool> = Lazy::new(|| var_is_true("MISE_LOG_VERBOSE_DEPS"));

pub static __USAGE: Lazy<Option<String>> = Lazy::new(|| var("__USAGE").ok());

Expand Down
41 changes: 39 additions & 2 deletions src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,52 @@ struct Logger {
log_file: Option<Mutex<File>>,
}

/// Third-party crate targets that emit very noisy debug logs (often per HTTP/2
/// frame, per socket read, etc.) and would otherwise overwhelm `-v` output.
/// These are suppressed at Debug level unless `MISE_LOG_VERBOSE_DEPS=1` is set.
/// Trace level always lets them through.
const NOISY_DEP_TARGETS: &[&str] = &[
"h2",
"hyper",
"hyper_util",
"mio",
"reqwest",
"rustls",
"tokio_util",
"tower",
"want",
];

fn is_noisy_dep_target(target: &str) -> bool {
NOISY_DEP_TARGETS
.iter()
.any(|t| target == *t || target.starts_with(&format!("{t}::")))
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Outdated
}
Comment on lines +43 to +50

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of is_noisy_dep_target uses format! inside a loop, which causes multiple string allocations for every log record at the Debug level. This can significantly impact performance when debug logging is enabled.

You can avoid these allocations by using strip_prefix and checking if the remainder is empty or starts with the :: separator.

Suggested change
fn is_noisy_dep_target(target: &str) -> bool {
NOISY_DEP_TARGETS
.iter()
.any(|t| target == *t || target.starts_with(&format!("{t}::")))
}
fn is_noisy_dep_target(target: &str) -> bool {
NOISY_DEP_TARGETS
.iter()
.any(|t| target.strip_prefix(*t).is_some_and(|rest| rest.is_empty() || rest.starts_with("::")))
}


impl log::Log for Logger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= *self.level.lock().unwrap()
}

fn log(&self, record: &Record) {
let term_level = *self.term_level.lock().unwrap();
let will_log_file = record.level() <= self.file_level && self.log_file.is_some();
let will_log_term = record.level() <= term_level;
let mut will_log_file = record.level() <= self.file_level && self.log_file.is_some();
let mut will_log_term = record.level() <= term_level;

// Suppress Debug-level spam from noisy third-party crates (e.g. h2
// logging every received DATA frame). Trace still passes through, as
// does any level when MISE_LOG_VERBOSE_DEPS=1.
if record.level() == Level::Debug
&& !*env::MISE_LOG_VERBOSE_DEPS
&& is_noisy_dep_target(record.target())
{
if self.file_level < LevelFilter::Trace {
will_log_file = false;
}
if term_level < LevelFilter::Trace {
will_log_term = false;
}
}

if !will_log_file && !will_log_term {
return;
Expand Down
Loading