commit 7eeee7dfc9d04d1791018c1577d9887f1588f782
parent d5a056c2b6a70ff711877d7c895af1967a7d4f17
Author: triesap <tyson@radroots.org>
Date: Sun, 22 Mar 2026 20:26:55 +0000
log: prefer explicit service filters over rust_log
- keep ambient RUST_LOG handling only for callers that do not pass a default filter
- let services such as myc honor their repo-configured logging filter deterministically
- add coverage for the explicit-filter precedence path in radroots-log tests
- preserve the existing fallback to info when no explicit filter is supplied
Diffstat:
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/crates/log/src/init.rs b/crates/log/src/init.rs
@@ -27,8 +27,7 @@ pub fn init_logging(opts: LoggingOptions) -> Result<()> {
None
};
- let env = EnvFilter::try_from_default_env()
- .unwrap_or_else(|_| EnvFilter::new(opts.default_level.as_deref().unwrap_or("info")));
+ let env = resolve_env_filter(opts.default_level.as_deref());
let fmt_layer_file = writer.as_ref().map(|w| {
fmt::layer()
.with_writer(w.clone())
@@ -59,6 +58,13 @@ pub fn init_logging(opts: LoggingOptions) -> Result<()> {
Ok(())
}
+fn resolve_env_filter(default_level: Option<&str>) -> EnvFilter {
+ match default_level {
+ Some(level) => EnvFilter::new(level),
+ None => EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
+ }
+}
+
pub fn init_stdout() -> Result<()> {
init_logging(LoggingOptions {
dir: None,
@@ -80,7 +86,7 @@ fn build_file_appender(dir: &std::path::Path, opts: &LoggingOptions) -> Result<R
#[cfg(test)]
mod tests {
- use super::{build_file_appender, init_logging};
+ use super::{build_file_appender, init_logging, resolve_env_filter};
use crate::{LogFileLayout, LoggingOptions};
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
@@ -179,4 +185,13 @@ mod tests {
assert!(first.is_ok());
let _ = std::fs::remove_dir_all(&dir);
}
+
+ #[test]
+ fn explicit_default_level_wins_over_ambient_rust_log() {
+ // Callers that pass an explicit service filter should not inherit the shell's RUST_LOG.
+ let env = resolve_env_filter(Some("info,myc=info"));
+ let rendered = env.to_string();
+ assert!(rendered.contains("info"));
+ assert!(rendered.contains("myc=info"));
+ }
}