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