152da9a59SGnoCiYeH use core::{
252da9a59SGnoCiYeH fmt::{self, Write},
352da9a59SGnoCiYeH sync::atomic::Ordering,
452da9a59SGnoCiYeH };
56cb769c4Slogin
68d72b68dSJomo use alloc::string::ToString;
72eab6dd7S曾俊 use log::{info, Level, Log};
88d72b68dSJomo
9fbe6becdSLoGin use super::lib_ui::textui::{textui_putstr, FontColor};
106cb769c4Slogin
118d72b68dSJomo use crate::{
12f3b05a97SGnoCiYeH driver::tty::{
13dfe53cf0SGnoCiYeH tty_driver::TtyOperation, tty_port::tty_port,
1452da9a59SGnoCiYeH virtual_terminal::virtual_console::CURRENT_VCNUM,
1552da9a59SGnoCiYeH },
168d72b68dSJomo filesystem::procfs::{
178d72b68dSJomo kmsg::KMSG,
188d72b68dSJomo log::{LogLevel, LogMessage},
198d72b68dSJomo },
206fc066acSJomo time::PosixTimeSpec,
218d72b68dSJomo };
228d72b68dSJomo
236cb769c4Slogin #[macro_export]
246cb769c4Slogin macro_rules! print {
256cb769c4Slogin ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*)));
266cb769c4Slogin }
276cb769c4Slogin
286cb769c4Slogin #[macro_export]
296cb769c4Slogin macro_rules! println {
306cb769c4Slogin () => {
316cb769c4Slogin $crate::print!("\n");
326cb769c4Slogin };
336cb769c4Slogin ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
346cb769c4Slogin }
356cb769c4Slogin
36fb6c29d0Slogin pub struct PrintkWriter;
37fb6c29d0Slogin
38fb6c29d0Slogin impl PrintkWriter {
3940fe15e0SLoGin #[inline]
__write_fmt(&mut self, args: fmt::Arguments)4040fe15e0SLoGin pub fn __write_fmt(&mut self, args: fmt::Arguments) {
41abe3a6eaShanjiezhou self.write_fmt(args).ok();
4240fe15e0SLoGin }
4340fe15e0SLoGin
44abe3a6eaShanjiezhou /// 并输出白底黑字
45fb6c29d0Slogin /// @param str: 要写入的字符
__write_string(&mut self, s: &str)46fb6c29d0Slogin pub fn __write_string(&mut self, s: &str) {
4752da9a59SGnoCiYeH let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
4852da9a59SGnoCiYeH if current_vcnum != -1 {
4952da9a59SGnoCiYeH // tty已经初始化了之后才输出到屏幕
50dfe53cf0SGnoCiYeH let port = tty_port(current_vcnum as usize);
51dfe53cf0SGnoCiYeH let tty = port.port_data().internal_tty();
52b5b571e0SLoGin if let Some(tty) = tty {
5352da9a59SGnoCiYeH let _ = tty.write(tty.core(), s.as_bytes(), s.len());
5452da9a59SGnoCiYeH } else {
5552da9a59SGnoCiYeH let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
56fb6c29d0Slogin }
5752da9a59SGnoCiYeH } else {
5852da9a59SGnoCiYeH let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
5952da9a59SGnoCiYeH }
6040fe15e0SLoGin }
61fb6c29d0Slogin }
62fb6c29d0Slogin
63fb6c29d0Slogin /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出
64fb6c29d0Slogin impl fmt::Write for PrintkWriter {
write_str(&mut self, s: &str) -> fmt::Result65fb6c29d0Slogin fn write_str(&mut self, s: &str) -> fmt::Result {
66fb6c29d0Slogin self.__write_string(s);
67fb6c29d0Slogin Ok(())
68fb6c29d0Slogin }
69fb6c29d0Slogin }
70fb6c29d0Slogin
71fb6c29d0Slogin #[doc(hidden)]
__printk(args: fmt::Arguments)72fb6c29d0Slogin pub fn __printk(args: fmt::Arguments) {
73fb6c29d0Slogin PrintkWriter.write_fmt(args).unwrap();
74fb6c29d0Slogin }
758d72b68dSJomo
768d72b68dSJomo pub struct Logger;
778d72b68dSJomo
788d72b68dSJomo impl Logger {
log(&self, log_level: usize, message: fmt::Arguments)798d72b68dSJomo pub fn log(&self, log_level: usize, message: fmt::Arguments) {
80453452ccSLoGin if unsafe { KMSG.is_some() } {
816fc066acSJomo let timestamp: PosixTimeSpec = PosixTimeSpec::now_cpu_time();
82b5b571e0SLoGin let log_level = LogLevel::from(log_level);
83453452ccSLoGin
848d72b68dSJomo let log_message = LogMessage::new(timestamp, log_level, message.to_string());
858d72b68dSJomo
868d72b68dSJomo unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) };
878d72b68dSJomo }
888d72b68dSJomo }
898d72b68dSJomo }
90731bc2b3SLoGin
91731bc2b3SLoGin /// 内核自定义日志器
92731bc2b3SLoGin ///
93*0897bd8eSLoGin /// todo: https://github.com/DragonOS-Community/DragonOS/issues/762
94*0897bd8eSLoGin struct KernelLogger;
95731bc2b3SLoGin
96*0897bd8eSLoGin impl Log for KernelLogger {
enabled(&self, _metadata: &log::Metadata) -> bool97731bc2b3SLoGin fn enabled(&self, _metadata: &log::Metadata) -> bool {
98731bc2b3SLoGin // 这里可以自定义日志过滤规则
99731bc2b3SLoGin true
100731bc2b3SLoGin }
101731bc2b3SLoGin
log(&self, record: &log::Record)102731bc2b3SLoGin fn log(&self, record: &log::Record) {
103731bc2b3SLoGin if self.enabled(record.metadata()) {
104731bc2b3SLoGin // todo: 接入kmsg
1052eab6dd7S曾俊 Self::kernel_log(record);
1062eab6dd7S曾俊 Self::iodisplay(record)
1072eab6dd7S曾俊 }
1082eab6dd7S曾俊 }
109731bc2b3SLoGin
flush(&self)1102eab6dd7S曾俊 fn flush(&self) {
1112eab6dd7S曾俊 // 如果需要的话,可以在这里实现缓冲区刷新逻辑
1122eab6dd7S曾俊 }
1132eab6dd7S曾俊 }
1142eab6dd7S曾俊
115*0897bd8eSLoGin impl KernelLogger {
iodisplay(record: &log::Record)1162eab6dd7S曾俊 fn iodisplay(record: &log::Record) {
1172eab6dd7S曾俊 match record.level() {
118*0897bd8eSLoGin Level::Debug | Level::Info | Level::Trace => {
1192eab6dd7S曾俊 write!(PrintkWriter, "[ {} ] ", record.level(),)
1202eab6dd7S曾俊 }
1212eab6dd7S曾俊 Level::Error => {
1222eab6dd7S曾俊 write!(PrintkWriter, "\x1B[41m[ ERROR ] \x1B[0m",)
1232eab6dd7S曾俊 }
1242eab6dd7S曾俊 Level::Warn => {
1252eab6dd7S曾俊 write!(PrintkWriter, "\x1B[1;33m[ WARN ] \x1B[0m",)
1262eab6dd7S曾俊 }
1272eab6dd7S曾俊 }
1282eab6dd7S曾俊 .unwrap();
129731bc2b3SLoGin writeln!(
130731bc2b3SLoGin PrintkWriter,
1312eab6dd7S曾俊 "({}:{})\t {}",
132731bc2b3SLoGin record.file().unwrap_or(""),
133731bc2b3SLoGin record.line().unwrap_or(0),
134731bc2b3SLoGin record.args()
135731bc2b3SLoGin )
136731bc2b3SLoGin .unwrap();
137731bc2b3SLoGin }
138731bc2b3SLoGin
kernel_log(record: &log::Record)1392eab6dd7S曾俊 fn kernel_log(record: &log::Record) {
1402eab6dd7S曾俊 match record.level() {
1412eab6dd7S曾俊 Level::Debug => Logger.log(
1422eab6dd7S曾俊 7,
1432eab6dd7S曾俊 format_args!(
1442eab6dd7S曾俊 "({}:{})\t {}\n",
1452eab6dd7S曾俊 record.file().unwrap_or(""),
1462eab6dd7S曾俊 record.line().unwrap_or(0),
1472eab6dd7S曾俊 record.args()
1482eab6dd7S曾俊 ),
1492eab6dd7S曾俊 ),
1502eab6dd7S曾俊 Level::Error => Logger.log(
1512eab6dd7S曾俊 3,
1522eab6dd7S曾俊 format_args!(
1532eab6dd7S曾俊 "({}:{})\t {}\n",
1542eab6dd7S曾俊 record.file().unwrap_or(""),
1552eab6dd7S曾俊 record.line().unwrap_or(0),
1562eab6dd7S曾俊 record.args()
1572eab6dd7S曾俊 ),
1582eab6dd7S曾俊 ),
1592eab6dd7S曾俊 Level::Info => Logger.log(
1602eab6dd7S曾俊 6,
1612eab6dd7S曾俊 format_args!(
1622eab6dd7S曾俊 "({}:{})\t {}\n",
1632eab6dd7S曾俊 record.file().unwrap_or(""),
1642eab6dd7S曾俊 record.line().unwrap_or(0),
1652eab6dd7S曾俊 record.args()
1662eab6dd7S曾俊 ),
1672eab6dd7S曾俊 ),
1682eab6dd7S曾俊 Level::Warn => Logger.log(
1692eab6dd7S曾俊 4,
1702eab6dd7S曾俊 format_args!(
1712eab6dd7S曾俊 "({}:{})\t {}\n",
1722eab6dd7S曾俊 record.file().unwrap_or(""),
1732eab6dd7S曾俊 record.line().unwrap_or(0),
1742eab6dd7S曾俊 record.args()
1752eab6dd7S曾俊 ),
1762eab6dd7S曾俊 ),
1772eab6dd7S曾俊 Level::Trace => {
1782eab6dd7S曾俊 todo!()
1792eab6dd7S曾俊 }
1802eab6dd7S曾俊 }
181731bc2b3SLoGin }
182731bc2b3SLoGin }
183731bc2b3SLoGin
early_init_logging()184731bc2b3SLoGin pub fn early_init_logging() {
185*0897bd8eSLoGin log::set_logger(&KernelLogger).unwrap();
186731bc2b3SLoGin log::set_max_level(log::LevelFilter::Debug);
187731bc2b3SLoGin info!("Logging initialized");
188731bc2b3SLoGin }
189