From 3cd3e3385f5d13150707c3425a6360817774f55a Mon Sep 17 00:00:00 2001 From: Tjardo Date: Wed, 11 Sep 2024 20:41:14 +0200 Subject: [PATCH] Add formatters --- README.md | 8 +++---- src/drivers/console.rs | 22 +++--------------- src/drivers/daily.rs | 14 ++++-------- src/drivers/single.rs | 14 ++++-------- src/drivers/stdout.rs | 12 ++++------ src/formatters/default.rs | 27 ++++++++++++++++++++++ src/formatters/mod.rs | 6 +++++ src/formatters/readable.rs | 46 ++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ src/writer.rs | 33 +++++++++++++++++++++++++++ 10 files changed, 133 insertions(+), 51 deletions(-) create mode 100644 src/formatters/default.rs create mode 100644 src/formatters/mod.rs create mode 100644 src/formatters/readable.rs create mode 100644 src/writer.rs diff --git a/README.md b/README.md index 23bb084..ea8fc83 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ Ftail::new() 2024-09-10 14:41:57 TRACE stdout This is a trace message 2024-09-10 14:41:57 DEBUG stdout This is a debug message 2024-09-10 14:41:57 INFO foo bar -2024-09-10 14:41:57 WARN stdout This is a warning -2024-09-10 14:41:57 ERROR stdout This is an error +2024-09-10 14:41:57 WARN stdout This is a warning message +2024-09-10 14:41:57 ERROR stdout This is an error message ``` ### Console @@ -74,11 +74,11 @@ bar examples\console\src/main.rs:12 2024-09-10 14:42:21 · WARN -This is a warning +This is a warning message examples\console\src/main.rs:14 2024-09-10 14:42:21 · ERROR -This is an error +This is an error message examples\console\src/main.rs:16 ``` diff --git a/src/drivers/console.rs b/src/drivers/console.rs index 2276531..91006f4 100644 --- a/src/drivers/console.rs +++ b/src/drivers/console.rs @@ -1,6 +1,6 @@ use log::Log; -use crate::ansi_escape::TextStyling; +use crate::formatters::{readable::ReadableFormatter, Formatter}; pub struct ConsoleLogger {} @@ -10,25 +10,9 @@ impl Log for ConsoleLogger { } fn log(&self, record: &log::Record) { - let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + let formatter = ReadableFormatter::new(record); - let level = match record.level() { - log::Level::Trace => record.level().bold().black(), - log::Level::Debug => record.level().bold().blue(), - log::Level::Info => record.level().bold().green(), - log::Level::Warn => record.level().bold().yellow(), - log::Level::Error => record.level().bold().red(), - }; - - println!("{} · {}", now.black(), level); - println!("{}", record.args().bold()); - println!( - "{}{}{}", - record.file().unwrap().black(), - ":".black(), - record.line().unwrap().black() - ); - println!(); + println!("{}", formatter.format()); } fn flush(&self) {} diff --git a/src/drivers/daily.rs b/src/drivers/daily.rs index 65a5bd9..2ef3367 100644 --- a/src/drivers/daily.rs +++ b/src/drivers/daily.rs @@ -5,6 +5,8 @@ use std::{ sync::Mutex, }; +use crate::formatters::{default::DefaultFormatter, Formatter}; + pub struct DailyLogger { file: Mutex>, dir: String, @@ -64,18 +66,10 @@ impl Log for DailyLogger { fn log(&self, record: &log::Record) { self.rotate_file_if_needed(); - let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); - - let line = format!( - "{} {} {} {}", - now, - record.level(), - record.target(), - record.args() - ); + let formatter = DefaultFormatter::new(record); let mut file = self.file.lock().unwrap(); - writeln!(file, "{}", line).unwrap(); + writeln!(file, "{}", formatter.format()).unwrap(); file.flush().unwrap(); } diff --git a/src/drivers/single.rs b/src/drivers/single.rs index cbec538..02b2fe6 100644 --- a/src/drivers/single.rs +++ b/src/drivers/single.rs @@ -5,6 +5,8 @@ use std::{ sync::Mutex, }; +use crate::formatters::{default::DefaultFormatter, Formatter}; + pub struct SingleLogger { file: Mutex>, } @@ -36,18 +38,10 @@ impl Log for SingleLogger { } fn log(&self, record: &log::Record) { - let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); - - let line = format!( - "{} {} {} {}", - now, - record.level(), - record.target(), - record.args() - ); + let formatter = DefaultFormatter::new(record); let mut file = self.file.lock().unwrap(); - writeln!(file, "{}", line).unwrap(); + writeln!(file, "{}", formatter.format()).unwrap(); file.flush().unwrap(); } diff --git a/src/drivers/stdout.rs b/src/drivers/stdout.rs index a706527..02e6d11 100644 --- a/src/drivers/stdout.rs +++ b/src/drivers/stdout.rs @@ -1,5 +1,7 @@ use log::Log; +use crate::formatters::{default::DefaultFormatter, Formatter}; + pub struct StdOutLogger {} impl Log for StdOutLogger { @@ -8,15 +10,9 @@ impl Log for StdOutLogger { } fn log(&self, record: &log::Record) { - let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); + let formatter = DefaultFormatter::new(record); - println!( - "{} {} {} {}", - now, - record.level(), - record.target(), - record.args() - ); + println!("{}", formatter.format()); } fn flush(&self) {} diff --git a/src/formatters/default.rs b/src/formatters/default.rs new file mode 100644 index 0000000..c99bbe8 --- /dev/null +++ b/src/formatters/default.rs @@ -0,0 +1,27 @@ +use crate::writer::LogWriter; + +use super::Formatter; + +pub struct DefaultFormatter<'a> { + record: &'a log::Record<'a>, +} + +impl DefaultFormatter<'_> { + pub fn new<'a>(record: &'a log::Record<'a>) -> DefaultFormatter<'a> { + DefaultFormatter { record } + } +} + +impl<'a> Formatter for DefaultFormatter<'a> { + fn format(&self) -> String { + let writer = LogWriter::new(); + + format!( + "{} {} {} {}", + writer.get_datetime(), + writer.get_level(self.record), + writer.get_target(self.record), + writer.get_args(self.record), + ) + } +} diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs new file mode 100644 index 0000000..bbeac95 --- /dev/null +++ b/src/formatters/mod.rs @@ -0,0 +1,6 @@ +pub mod default; +pub mod readable; + +pub trait Formatter { + fn format(&self) -> String; +} diff --git a/src/formatters/readable.rs b/src/formatters/readable.rs new file mode 100644 index 0000000..18dac80 --- /dev/null +++ b/src/formatters/readable.rs @@ -0,0 +1,46 @@ +use crate::{ansi_escape::TextStyling, writer::LogWriter}; + +use super::Formatter; + +pub struct ReadableFormatter<'a> { + record: &'a log::Record<'a>, +} + +impl ReadableFormatter<'_> { + pub fn new<'a>(record: &'a log::Record<'a>) -> ReadableFormatter<'a> { + ReadableFormatter { record } + } +} + +impl<'a> Formatter for ReadableFormatter<'a> { + fn format(&self) -> String { + let writer = LogWriter::new(); + + let mut result = String::new(); + + let level = match self.record.level() { + log::Level::Trace => writer.get_level(self.record).bold().black(), + log::Level::Debug => writer.get_level(self.record).bold().blue(), + log::Level::Info => writer.get_level(self.record).bold().green(), + log::Level::Warn => writer.get_level(self.record).bold().yellow(), + log::Level::Error => writer.get_level(self.record).bold().red(), + }; + + result.push_str(&format!("{} · {}\n", writer.get_datetime().black(), level)); + result.push_str(&format!("{}\n", writer.get_args(self.record).bold())); + + let file = writer.get_file(self.record); + let line = writer.get_line(self.record); + + if file.is_some() && line.is_some() { + result.push_str(&format!( + "{}{}{}\n", + file.unwrap().black(), + ":".black(), + line.unwrap().black() + )); + } + + result + } +} diff --git a/src/lib.rs b/src/lib.rs index 48748ba..024ed37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,8 @@ use log::Log; mod ansi_escape; pub mod drivers; pub mod error; +mod formatters; +mod writer; pub(crate) struct LogDriver { driver: Box, diff --git a/src/writer.rs b/src/writer.rs new file mode 100644 index 0000000..e9de02f --- /dev/null +++ b/src/writer.rs @@ -0,0 +1,33 @@ +use log::Record; + +pub struct LogWriter {} + +impl LogWriter { + pub fn new() -> Self { + Self {} + } + + pub fn get_datetime(&self) -> String { + chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string() + } + + pub fn get_level(&self, record: &Record) -> String { + record.level().to_string() + } + + pub fn get_target(&self, record: &Record) -> String { + record.target().to_string() + } + + pub fn get_args(&self, record: &Record) -> String { + record.args().to_string() + } + + pub fn get_file(&self, record: &Record) -> Option { + record.file().map(|f| f.to_string()) + } + + pub fn get_line(&self, record: &Record) -> Option { + record.line() + } +}