From b7a07d577d59eb18a371aa57349ce913604908b7 Mon Sep 17 00:00:00 2001 From: YushiOMOTE Date: Sat, 13 Jul 2024 17:50:23 +0900 Subject: [PATCH 1/2] Support custom formatter --- src/lib.rs | 2 +- src/logger.rs | 79 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 63de775..4193275 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,5 +8,5 @@ mod logger; /// The module for the serial port driver. mod serial; -pub use crate::logger::{builder, init, init_with_filter, Builder}; +pub use crate::logger::{builder, init, init_with_filter, Builder, Formatter}; pub use crate::serial::Serial; diff --git a/src/logger.rs b/src/logger.rs index cf8ee6a..0b33a99 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,13 +1,44 @@ use crate::serial::Serial; -use core::{fmt::write, format_args}; +use core::{fmt::Write, writeln}; use log::*; use spin::Mutex; const COM1_PORT: u16 = 0x3f8; -static LOGGER: Logger = Logger(Mutex::new(COM1_PORT)); +static LOGGER: Logger = Logger::new(COM1_PORT); -struct Logger(Mutex); +/// Formatter that converts log records into desirable text format. +pub type Formatter = fn(&mut dyn Write, &Record) -> Result<(), core::fmt::Error>; + +struct Inner { + base: u16, + formatter: Formatter, +} + +struct Logger { + inner: Mutex, +} + +impl Logger { + const fn new(base: u16) -> Self { + Logger { + inner: Mutex::new(Inner { + base, + formatter: default_formatter, + }), + } + } + + fn set_base(&self, new_base: u16) { + let mut inner = self.inner.lock(); + inner.base = new_base; + } + + fn set_formatter(&self, new_formatter: Formatter) { + let mut inner = self.inner.lock(); + inner.formatter = new_formatter; + } +} impl log::Log for Logger { fn enabled(&self, _m: &Metadata) -> bool { @@ -15,28 +46,25 @@ impl log::Log for Logger { } fn log(&self, record: &Record) { - let port = self.0.lock(); - let mut serial = Serial::new(*port); - - let _ = write( - &mut serial, - format_args!( - "{:>8}: {} ({}, {}:{})\n", - record.level(), - record.args(), - record.target(), - record.file().unwrap_or(""), - record.line().unwrap_or(0), - ), - ); + let inner = self.inner.lock(); + let mut serial = Serial::new(inner.base); + + let _ = (inner.formatter)(&mut serial, record); } fn flush(&self) {} } -fn set_logger_base(base: u16) { - let mut data = LOGGER.0.lock(); - *data = base; +fn default_formatter(buffer: &mut dyn Write, record: &Record) -> Result<(), core::fmt::Error> { + writeln!( + buffer, + "{:>8}: {} ({}, {}:{})\n", + record.level(), + record.args(), + record.target(), + record.file().unwrap_or(""), + record.line().unwrap_or(0) + ) } /// The builder for a serial port logger. @@ -45,6 +73,7 @@ fn set_logger_base(base: u16) { pub struct Builder { base: u16, filter: LevelFilter, + formatter: Formatter, } impl Builder { @@ -53,6 +82,7 @@ impl Builder { Self { base: COM1_PORT, filter: LevelFilter::Info, + formatter: default_formatter, } } @@ -68,13 +98,20 @@ impl Builder { self } + /// Set formatter. + pub fn formatter(mut self, formatter: Formatter) -> Self { + self.formatter = formatter; + self + } + /// Setup a logger based on the configuration. pub fn setup(self) { // Initialize serial port Serial::new(self.base).init(); // Update base address of logger - set_logger_base(self.base); + LOGGER.set_base(self.base); + LOGGER.set_formatter(self.formatter); set_logger(&LOGGER).unwrap(); set_max_level(self.filter); From e949ed2967b78bd6470833e858cc6da289a933b7 Mon Sep 17 00:00:00 2001 From: YushiOMOTE Date: Sat, 13 Jul 2024 17:50:47 +0900 Subject: [PATCH 2/2] Add formatter to documentation --- README.md | 1 + src/logger.rs | 1 + src/serial.rs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a58615..03ce3e9 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ fn main() { com_logger::builder() .base(0x2f8) // Use COM2 port .filter(LevelFilter::Debug) // Print debug log + .formatter(|buf, record| writeln!(buf, "{}", record.args())) // Define own format .setup(); debug!("Hello"); diff --git a/src/logger.rs b/src/logger.rs index 0b33a99..a5344fc 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -129,6 +129,7 @@ impl Builder { /// com_logger::builder() /// .base(0x2f8) // Use COM2 port /// .filter(LevelFilter::Debug) // Print debug log +/// .formatter(|buf, record| writeln!(buf, "{}", record.args())) // Define own format /// .setup(); /// /// debug!("Hello"); diff --git a/src/serial.rs b/src/serial.rs index 7a090be..6446060 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -5,6 +5,7 @@ use uart_16550::SerialPort; /// /// ```rust,no_run /// use com_logger::Serial; +/// use core::fmt::Write; /// /// fn main() { /// // Setup COM1 serial port. @@ -15,7 +16,7 @@ use uart_16550::SerialPort; /// s.write(b'P'); /// /// // Write the string to the serial port. -/// core::fmt::write(&mut s, format_args!("Hello {}", 0xdead)); +/// writeln!(&mut s, "Hello {}", 0xdead); /// } /// ``` pub struct Serial(SerialPort);