1 use core::fmt::{self, Write}; 2 3 use alloc::string::ToString; 4 use log::{info, Level, Log}; 5 6 use super::lib_ui::textui::{textui_putstr, FontColor}; 7 8 use crate::{ 9 driver::tty::{tty_driver::TtyOperation, virtual_terminal::vc_manager}, 10 filesystem::procfs::{ 11 kmsg::KMSG, 12 log::{LogLevel, LogMessage}, 13 }, 14 time::PosixTimeSpec, 15 }; 16 17 #[macro_export] 18 macro_rules! print { 19 ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*))); 20 } 21 22 #[macro_export] 23 macro_rules! println { 24 () => { 25 $crate::print!("\n"); 26 }; 27 ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); 28 } 29 30 pub struct PrintkWriter; 31 32 impl PrintkWriter { 33 #[inline] 34 pub fn __write_fmt(&mut self, args: fmt::Arguments) { 35 self.write_fmt(args).ok(); 36 } 37 38 /// 并输出白底黑字 39 /// @param str: 要写入的字符 40 pub fn __write_string(&mut self, s: &str) { 41 if let Some(current_vc) = vc_manager().current_vc() { 42 // tty已经初始化了之后才输出到屏幕 43 let port = current_vc.port(); 44 let tty = port.port_data().internal_tty(); 45 if let Some(tty) = tty { 46 let _ = tty.write(tty.core(), s.as_bytes(), s.len()); 47 } else { 48 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 49 } 50 } else { 51 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 52 } 53 } 54 } 55 56 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出 57 impl fmt::Write for PrintkWriter { 58 fn write_str(&mut self, s: &str) -> fmt::Result { 59 self.__write_string(s); 60 Ok(()) 61 } 62 } 63 64 #[doc(hidden)] 65 pub fn __printk(args: fmt::Arguments) { 66 PrintkWriter.write_fmt(args).unwrap(); 67 } 68 69 pub struct Logger; 70 71 impl Logger { 72 pub fn log(&self, log_level: usize, message: fmt::Arguments) { 73 if unsafe { KMSG.is_some() } { 74 let timestamp: PosixTimeSpec = PosixTimeSpec::now_cpu_time(); 75 let log_level = LogLevel::from(log_level); 76 77 let log_message = LogMessage::new(timestamp, log_level, message.to_string()); 78 79 unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) }; 80 } 81 } 82 } 83 84 /// 内核自定义日志器 85 /// 86 /// todo: https://github.com/DragonOS-Community/DragonOS/issues/762 87 struct KernelLogger; 88 89 impl Log for KernelLogger { 90 fn enabled(&self, _metadata: &log::Metadata) -> bool { 91 // 这里可以自定义日志过滤规则 92 true 93 } 94 95 fn log(&self, record: &log::Record) { 96 if self.enabled(record.metadata()) { 97 // todo: 接入kmsg 98 Self::kernel_log(record); 99 Self::iodisplay(record) 100 } 101 } 102 103 fn flush(&self) { 104 // 如果需要的话,可以在这里实现缓冲区刷新逻辑 105 } 106 } 107 108 impl KernelLogger { 109 fn iodisplay(record: &log::Record) { 110 match record.level() { 111 Level::Debug | Level::Info | Level::Trace => { 112 write!(PrintkWriter, "[ {} ] ", record.level(),) 113 } 114 Level::Error => { 115 write!(PrintkWriter, "\x1B[41m[ ERROR ] \x1B[0m",) 116 } 117 Level::Warn => { 118 write!(PrintkWriter, "\x1B[1;33m[ WARN ] \x1B[0m",) 119 } 120 } 121 .unwrap(); 122 writeln!( 123 PrintkWriter, 124 "({}:{})\t {}", 125 record.file().unwrap_or(""), 126 record.line().unwrap_or(0), 127 record.args() 128 ) 129 .unwrap(); 130 } 131 132 fn kernel_log(record: &log::Record) { 133 match record.level() { 134 Level::Debug => Logger.log( 135 7, 136 format_args!( 137 "({}:{})\t {}\n", 138 record.file().unwrap_or(""), 139 record.line().unwrap_or(0), 140 record.args() 141 ), 142 ), 143 Level::Error => Logger.log( 144 3, 145 format_args!( 146 "({}:{})\t {}\n", 147 record.file().unwrap_or(""), 148 record.line().unwrap_or(0), 149 record.args() 150 ), 151 ), 152 Level::Info => Logger.log( 153 6, 154 format_args!( 155 "({}:{})\t {}\n", 156 record.file().unwrap_or(""), 157 record.line().unwrap_or(0), 158 record.args() 159 ), 160 ), 161 Level::Warn => Logger.log( 162 4, 163 format_args!( 164 "({}:{})\t {}\n", 165 record.file().unwrap_or(""), 166 record.line().unwrap_or(0), 167 record.args() 168 ), 169 ), 170 Level::Trace => { 171 todo!() 172 } 173 } 174 } 175 } 176 177 pub fn early_init_logging() { 178 log::set_logger(&KernelLogger).unwrap(); 179 log::set_max_level(log::LevelFilter::Debug); 180 info!("Logging initialized"); 181 } 182