Files
iris/src/desktop/logging.rs
T
2026-09-11 00:55:33 -04:00

60 lines
1.9 KiB
Rust

use std::io::Write;
use log::{Level, LevelFilter, Log, Metadata, Record};
/// Reads one level name from `RUST_LOG` -- `off`, `error`, `warn`,
/// `info`, `debug`, `trace`, case-insensitively. **Not env_logger's
/// per-module filter syntax**: anything else is ignored and the default
/// stands, rather than being silently read as "off", since a typo that
/// turned logging off would be indistinguishable from a quiet program.
fn level_from_env(default: LevelFilter) -> LevelFilter {
match std::env::var("RUST_LOG") {
Ok(text) => text.trim().parse().unwrap_or(default),
Err(_) => default,
}
}
struct StderrLogger {
level: LevelFilter,
}
impl Log for StderrLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &Record) {
if !self.enabled(record.metadata()) {
return;
}
// One write, not a `writeln!` per part: two threads logging at
// once interleave otherwise, and the frame and input traces are
// both written from whichever thread produced them.
let line = format!(
"{level:<5} {target}: {args}\n",
level = match record.level() {
Level::Error => "ERROR",
Level::Warn => "WARN",
Level::Info => "INFO",
Level::Debug => "DEBUG",
Level::Trace => "TRACE",
},
target = record.target(),
args = record.args(),
);
let _ = std::io::stderr().write_all(line.as_bytes());
}
fn flush(&self) {
let _ = std::io::stderr().flush();
}
}
pub fn install(default: LevelFilter) {
let level = level_from_env(default);
let logger = Box::leak(Box::new(StderrLogger { level }));
if log::set_logger(logger).is_ok() {
log::set_max_level(level);
}
}