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
kmsg_init()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 {
new() -> Self44 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 /// 添加日志消息
push(&mut self, msg: LogMessage)54 pub fn push(&mut self, msg: LogMessage) {
55 self.buffer.push(msg);
56 self.is_changed = true;
57 }
58
59 /// 读取缓冲区
read(&mut self, buf: &mut [u8]) -> Result<usize, SystemError>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 /// 读取缓冲区所有日志消息
read_all(&mut self, buf: &mut [u8]) -> Result<usize, SystemError>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的日志消息
read_level(&mut self, buf: &mut [u8]) -> Result<usize, SystemError>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 /// 读取并清空缓冲区
read_clear(&mut self, buf: &mut [u8]) -> Result<usize, SystemError>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 /// 清空缓冲区
clear(&mut self) -> Result<usize, SystemError>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 /// 设置输出到控制台的日志级别
set_level(&mut self, log_level: usize) -> Result<usize, SystemError>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
tobytes(&mut self) -> usize139 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 // 返回内核缓冲区所占字节数
data_size(&mut self) -> Result<usize, SystemError>156 pub fn data_size(&mut self) -> Result<usize, SystemError> {
157 return Ok(self.tobytes());
158 }
159 }
160