use core::fmt::Write; use log::{Level, LevelFilter, Metadata, Record, SetLoggerError}; use crate::logger::serial::{write_com, ANSI_COLORS, COM0}; use crate::std::vga::text::{Color, ColorCode, WRITER}; pub mod serial; #[macro_use] pub mod macros; pub static LOGGER: KLogger = KLogger; pub struct KLogger; const C_TRACE: ColorCode = ColorCode::new(Color::Cyan, Color::Black); const C_DEBUG: ColorCode = ColorCode::new(Color::Blue, Color::Black); const C_INFO: ColorCode = ColorCode::new(Color::Green, Color::Black); const C_WARN: ColorCode = ColorCode::new(Color::Yellow, Color::Black); const C_ERROR: ColorCode = ColorCode::new(Color::Red, Color::Black); const C_NORMAL: ColorCode = ColorCode::new(Color::White, Color::Black); impl log::Log for KLogger { fn enabled(&self, _: &Metadata) -> bool { true } fn log(&self, record: &Record) { if self.enabled(record.metadata()) { if !crate::std::vga::video::is_video_mode_enabled() { self.log_vga(record).unwrap(); } self.log_serial(record) } } fn flush(&self) {} } impl KLogger { fn log_vga(&self, record: &Record) -> core::fmt::Result { let mut f = WRITER.lock(); f.set_color(Color::Magenta, Color::Black); write!(f, "[")?; match record.level() { Level::Trace => { f.set_color_code(C_TRACE); write!(f, "TRACE")?; } Level::Debug => { f.set_color_code(C_DEBUG); write!(f, "DEBUG")?; } Level::Info => { f.set_color_code(C_INFO); write!(f, "INFO")?; } Level::Warn => { f.set_color_code(C_WARN); write!(f, "WARN")?; } Level::Error => { f.set_color_code(C_ERROR); write!(f, "ERROR")?; } } f.set_color(Color::Magenta, Color::Black); write!(f, "]")?; f.set_color_code(C_NORMAL); writeln!(f, " {}: {}", record.module_path().unwrap_or(""), record.args())?; Ok(()) } fn log_serial(&self, record: &Record) { {WRITER.lock().set_color(Color::Magenta, Color::Black); } write_com(&COM0, format_args!("{}[", ANSI_COLORS::MAGENTA)); match record.level() { Level::Trace => { write_com(&COM0, format_args!("{}TRACE", ANSI_COLORS::BLUE2)); } Level::Debug => { write_com(&COM0, format_args!("{}DEBUG", ANSI_COLORS::BLUE)); } Level::Info => { write_com(&COM0, format_args!("{}INFO", ANSI_COLORS::GREEN)); } Level::Warn => { write_com(&COM0, format_args!("{}WARN", ANSI_COLORS::YELLOW)); } Level::Error => { write_com(&COM0, format_args!("{}ERROR", ANSI_COLORS::RED)); } } write_com(&COM0, format_args!("{}]", ANSI_COLORS::MAGENTA)); write_com(&COM0, format_args!(" {}{}: {}\n", ANSI_COLORS::RESET, record.module_path().unwrap_or(""), record.args())); } } pub fn init(lvl: LevelFilter) -> Result<(), SetLoggerError> { log::set_logger(&LOGGER)?; log::set_max_level(lvl); log::info!("Logger init OK"); Ok(()) }