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:
2026-04-12 20:45:36 +02:00
parent b26206eb96
commit 0e3786a588

View 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) {}
}