use crate::kmain::KERNEL_CONF; use crate::network::socket::{SimpleSock, Socket}; use crate::time::fetch_time; use lliw::{Fg, Reset}; use log::{Level, Metadata, Record}; use log::{LevelFilter, SetLoggerError}; static LOGGER: SimpleLogger = SimpleLogger; // TODO: Rebuild this to take advantage of sockets // DETAIL: Log to a socket instead of the screen // So that we can log in the kernel and display it in userland struct SimpleLogger; impl log::Log for SimpleLogger { fn enabled(&self, metadata: &Metadata) -> bool { metadata.level() <= Level::Trace } fn log(&self, record: &Record) { if self.enabled(record.metadata()) { let time_float = fetch_time(); let color = match record.level() { log::Level::Error => (Fg::Red, "$RED$"), log::Level::Warn => (Fg::LightYellow, "$LIGHTYELLOW$"), log::Level::Info => (Fg::LightWhite, "$LIGHTGRAY$"), log::Level::Debug => (Fg::Blue, "$BLUE$"), log::Level::Trace => (Fg::Yellow, "$YELLOW$"), }; let msg = format!( "[{}{}$RESET$][$GREEN${}$RESET$]{}\n", color.1, record.level(), time_float, record.args() ); // kprint!("{}", msg); if KERNEL_CONF.logging.log_to_serial { serial_println!( "[{}{}{}][{}{}{}] {}", color.0, record.level(), Fg::Reset, Fg::Green, time_float, Reset, record.args() ); } let log_socket_id = SimpleSock::grab_socket("Logger".to_string()); match log_socket_id { Some(mut log_socket_id) => { log_socket_id.write(msg.as_bytes().to_vec()); } None => warn!("No socket found for Logger"), } } } /// Clear the log buffer fn flush(&self) {} } pub fn init() -> Result<(), SetLoggerError> { log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace)) }