diff --git a/Cargo.lock b/Cargo.lock index 237a89213f..374e6dbe57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,7 @@ dependencies = [ "aarch64", "ahash", "align-address", + "anstyle", "anyhow", "arm-gic", "async-lock", diff --git a/Cargo.toml b/Cargo.toml index baa53654ef..7867767550 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,6 +102,7 @@ async-trait = "0.1.80" async-lock = { version = "3.3.0", default-features = false } simple-shell = { version = "0.0.1", optional = true } volatile = "0.5.4" +anstyle = { version = "1", default-features = false } [dependencies.smoltcp] version = "0.11" diff --git a/src/logging.rs b/src/logging.rs index 905268a9ba..e47d053e06 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -1,4 +1,7 @@ -use log::{LevelFilter, Metadata, Record}; +use core::fmt; + +use anstyle::AnsiColor; +use log::{Level, LevelFilter, Metadata, Record}; /// Data structure to filter kernel messages struct KernelLogger; @@ -17,13 +20,40 @@ impl log::Log for KernelLogger { println!( "[{}][{}] {}", crate::arch::core_local::core_id(), - record.level(), + ColorLevel(record.level()), record.args() ); } } } +struct ColorLevel(Level); + +impl fmt::Display for ColorLevel { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let level = self.0; + + if no_color() { + write!(f, "{level}") + } else { + let color = match level { + Level::Trace => AnsiColor::Magenta, + Level::Debug => AnsiColor::Blue, + Level::Info => AnsiColor::Green, + Level::Warn => AnsiColor::Yellow, + Level::Error => AnsiColor::Red, + }; + + let style = anstyle::Style::new().fg_color(Some(color.into())); + write!(f, "{style}{level}{style:#}") + } + } +} + +fn no_color() -> bool { + option_env!("NO_COLOR").is_some_and(|val| !val.is_empty()) +} + pub unsafe fn init() { log::set_logger(&KernelLogger).expect("Can't initialize logger"); // Determines LevelFilter at compile time