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