1 use super::log::{LogLevel, LogMessage}; 2 3 use crate::libs::spinlock::SpinLock; 4 5 use alloc::{borrow::ToOwned, string::ToString, vec::Vec}; 6 7 use kdepends::ringbuffer::{AllocRingBuffer, RingBuffer}; 8 9 use system_error::SystemError; 10 11 /// 缓冲区容量 12 const KMSG_BUFFER_CAPACITY: usize = 1024; 13 14 /// 全局环形缓冲区 15 pub static mut KMSG: Option<SpinLock<Kmsg>> = None; 16 17 /// 初始化KMSG 18 pub fn kmsg_init() { 19 let kmsg = SpinLock::new(Kmsg::new()); 20 unsafe { KMSG = Some(kmsg) }; 21 } 22 23 /// 日志 24 pub struct Kmsg { 25 /// 环形缓冲区 26 buffer: AllocRingBuffer<LogMessage>, 27 /// 缓冲区字节数组 28 data: Vec<u8>, 29 /// 能够输出到控制台的日志级别,当console_loglevel为DEFAULT时,表示可以打印所有级别的日志消息到控制台 30 console_loglevel: LogLevel, 31 /// 判断buffer在上一次转成字节数组之后是否发生变动 32 is_changed: bool, 33 } 34 35 impl Kmsg { 36 pub fn new() -> Self { 37 Kmsg { 38 buffer: AllocRingBuffer::new(KMSG_BUFFER_CAPACITY), 39 data: Vec::new(), 40 console_loglevel: LogLevel::DEFAULT, 41 is_changed: false, 42 } 43 } 44 45 /// 添加日志消息 46 pub fn push(&mut self, msg: LogMessage) { 47 self.buffer.push(msg); 48 self.is_changed = true; 49 } 50 51 /// 读取缓冲区 52 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> { 53 self.tobytes(); 54 55 match self.console_loglevel { 56 LogLevel::DEFAULT => self.read_all(buf), 57 _ => self.read_level(buf), 58 } 59 } 60 61 /// 读取缓冲区所有日志消息 62 fn read_all(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> { 63 let len = self.data.len().min(buf.len()); 64 65 // 拷贝数据 66 let src = &self.data[0..len]; 67 buf[0..src.len()].copy_from_slice(src); 68 69 return Ok(src.len()); 70 } 71 72 /// 读取缓冲区特定level的日志消息 73 fn read_level(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> { 74 let mut data_level: Vec<u8> = Vec::new(); 75 76 for msg in self.buffer.iter() { 77 if msg.level() == self.console_loglevel { 78 data_level.append(&mut msg.to_string().as_bytes().to_owned()); 79 } 80 } 81 82 let len = data_level.len().min(buf.len()); 83 84 // 拷贝数据 85 let src = &data_level[0..len]; 86 buf[0..src.len()].copy_from_slice(src); 87 88 // 将控制台输出日志level改回默认,否则之后都是打印特定level的日志消息 89 self.console_loglevel = LogLevel::DEFAULT; 90 91 return Ok(data_level.len()); 92 } 93 94 /// 读取并清空缓冲区 95 pub fn read_clear(&mut self, buf: &mut [u8]) -> Result<usize, SystemError> { 96 let r = self.read_all(buf); 97 self.clear()?; 98 99 return r; 100 } 101 102 /// 清空缓冲区 103 pub fn clear(&mut self) -> Result<usize, SystemError> { 104 self.buffer.clear(); 105 self.data.clear(); 106 107 return Ok(0); 108 } 109 110 /// 设置输出到控制台的日志级别 111 pub fn set_level(&mut self, log_level: usize) -> Result<usize, SystemError> { 112 let log_level = log_level - 1; 113 114 self.console_loglevel = match log_level { 115 0 => LogLevel::EMERG, 116 1 => LogLevel::ALERT, 117 2 => LogLevel::CRIT, 118 3 => LogLevel::ERR, 119 4 => LogLevel::WARN, 120 5 => LogLevel::NOTICE, 121 6 => LogLevel::INFO, 122 7 => LogLevel::DEBUG, 123 8 => LogLevel::DEFAULT, 124 _ => return Err(SystemError::EINVAL), 125 }; 126 127 return Ok(0); 128 } 129 130 /// 将环形缓冲区的日志消息转成字节数组以拷入用户buf 131 fn tobytes(&mut self) -> usize { 132 if self.is_changed { 133 self.data.clear(); 134 135 if self.console_loglevel == LogLevel::DEFAULT { 136 for msg in self.buffer.iter() { 137 self.data.append(&mut msg.to_string().as_bytes().to_owned()); 138 } 139 } 140 141 self.is_changed = false; 142 } 143 144 return self.data.len(); 145 } 146 147 // 返回内核缓冲区所占字节数 148 pub fn data_size(&mut self) -> Result<usize, SystemError> { 149 return Ok(self.tobytes()); 150 } 151 } 152