Add InterceptorLogger for async log capturing and enhanced debugging
- Implemented `InterceptorLogger` to enable async and sync log capture. - Integrated log interception for easier diagnostics and debugging. - Allowed log redirection to serial output via `esp_println`.
This commit is contained in:
65
Software/MainBoard/rust/src/log/interceptor.rs
Normal file
65
Software/MainBoard/rust/src/log/interceptor.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::blocking_mutex::Mutex as BlockingMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use log::{LevelFilter, Log, Metadata, Record};
|
||||
|
||||
pub struct InterceptorLogger {
|
||||
// Async mutex for start/stop capture from async context
|
||||
async_capture: Mutex<CriticalSectionRawMutex, ()>,
|
||||
// Blocking mutex for the actual data to be used in sync log()
|
||||
sync_capture: BlockingMutex<CriticalSectionRawMutex, core::cell::RefCell<Option<Vec<String>>>>,
|
||||
}
|
||||
|
||||
impl InterceptorLogger {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
async_capture: Mutex::new(()),
|
||||
sync_capture: BlockingMutex::new(core::cell::RefCell::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start_capture(&self) {
|
||||
let _guard = self.async_capture.lock().await;
|
||||
self.sync_capture.lock(|capture| {
|
||||
*capture.borrow_mut() = Some(Vec::new());
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn stop_capture(&self) -> Option<Vec<String>> {
|
||||
let _guard = self.async_capture.lock().await;
|
||||
self.sync_capture
|
||||
.lock(|capture| capture.borrow_mut().take())
|
||||
}
|
||||
|
||||
pub fn init(&'static self) {
|
||||
log::set_logger(self)
|
||||
.map(|()| log::set_max_level(LevelFilter::Info))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Log for InterceptorLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
metadata.level() <= log::Level::Info
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
if self.enabled(record.metadata()) {
|
||||
let message = alloc::format!("{}", record.args());
|
||||
|
||||
// Print to serial using esp_println
|
||||
esp_println::println!("{}: {}", record.level(), message);
|
||||
|
||||
// Capture if active
|
||||
self.sync_capture.lock(|capture| {
|
||||
if let Some(ref mut buffer) = *capture.borrow_mut() {
|
||||
buffer.push(alloc::format!("{}: {}", record.level(), message));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
Reference in New Issue
Block a user