2023-05-25 07:04:19 -05:00
|
|
|
// TODO: Add a logger api with logger levels and various outputs
|
2023-09-17 17:13:23 -05:00
|
|
|
pub static TERMINAL_LOGGER: Lazy<Mutex<TermLogger>> = Lazy::new(|| Mutex::new(TermLogger::new()));
|
2023-05-25 07:04:19 -05:00
|
|
|
|
2023-09-17 17:13:23 -05:00
|
|
|
use {
|
|
|
|
limine::{TerminalRequest, TerminalResponse},
|
|
|
|
log::{Level, SetLoggerError},
|
|
|
|
spin::{lazy::Lazy, mutex::Mutex},
|
|
|
|
};
|
2023-03-30 16:43:04 -05:00
|
|
|
|
|
|
|
pub fn init() -> Result<(), SetLoggerError> {
|
|
|
|
log::set_logger(&crate::logger::Logger)?;
|
2023-09-17 16:03:32 -05:00
|
|
|
log::set_max_level(log::LevelFilter::Debug);
|
2023-09-17 17:13:23 -05:00
|
|
|
|
|
|
|
Lazy::force(&TERMINAL_LOGGER);
|
|
|
|
|
2023-03-30 16:43:04 -05:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Logger;
|
|
|
|
impl log::Log for Logger {
|
2023-05-23 05:16:14 -05:00
|
|
|
fn enabled(&self, _metadata: &log::Metadata) -> bool {
|
2023-03-30 16:43:04 -05:00
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log(&self, record: &log::Record) {
|
|
|
|
let lvl = record.level();
|
2023-07-12 12:22:13 -05:00
|
|
|
let lvl_color = match lvl {
|
|
|
|
Level::Error => "160",
|
|
|
|
Level::Warn => "172",
|
|
|
|
Level::Info => "47",
|
|
|
|
Level::Debug => "25",
|
|
|
|
Level::Trace => "103",
|
|
|
|
};
|
|
|
|
let module = record.module_path().unwrap_or_default();
|
|
|
|
let line = record.line().unwrap_or_default();
|
2023-03-30 16:43:04 -05:00
|
|
|
crate::arch::log(format_args!(
|
2023-07-12 12:22:13 -05:00
|
|
|
"\x1b[38;5;{lvl_color}m{lvl}\x1b[0m [{module}:{line}]: {}\r\n",
|
2023-03-30 16:43:04 -05:00
|
|
|
record.args(),
|
|
|
|
))
|
|
|
|
.expect("write to serial console");
|
|
|
|
}
|
|
|
|
|
|
|
|
fn flush(&self) {}
|
|
|
|
}
|
2023-09-17 17:13:23 -05:00
|
|
|
|
|
|
|
pub struct TermLogger(&'static TerminalResponse);
|
|
|
|
unsafe impl Send for TermLogger {}
|
|
|
|
impl TermLogger {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
static TERM_REQ: TerminalRequest = TerminalRequest::new(0);
|
|
|
|
Self(
|
|
|
|
TERM_REQ
|
|
|
|
.get_response()
|
|
|
|
.get()
|
|
|
|
.expect("failed to get terminal response"),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl core::fmt::Write for TermLogger {
|
|
|
|
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
|
|
|
if let (Some(w), ts) = (self.0.write(), self.0.terminals()) {
|
|
|
|
for term in ts {
|
|
|
|
w(term, s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|