From 53b4eacc118df51b86bd294e57896ec26e61fe33 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 17 Mar 2019 16:47:01 +0900 Subject: [PATCH 1/2] Add `BuildWithCustomFormat` trait --- src/build.rs | 14 +++++++++++++- src/file.rs | 18 ++++++++++++++++-- src/lib.rs | 2 +- src/terminal.rs | 18 ++++++++++++++++-- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/build.rs b/src/build.rs index 71c68c3..d957e87 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,4 +1,6 @@ -use slog::Logger; +use slog::{Drain, Logger}; +use slog_term::Decorator; +use std::fmt::Debug; use file::FileLoggerBuilder; use null::NullLoggerBuilder; @@ -11,6 +13,16 @@ pub trait Build { fn build(&self) -> Result; } +pub trait BuildWithCustomFormat { + type Decorator: Decorator; + + fn build_with_custom_format(&self, f: F) -> Result + where + F: FnOnce(Self::Decorator) -> Result, + D: Drain + Send + 'static, + D::Err: Debug; +} + /// Logger builder. #[derive(Debug)] #[allow(clippy::large_enum_variant)] diff --git a/src/file.rs b/src/file.rs index 582415c..a148de3 100644 --- a/src/file.rs +++ b/src/file.rs @@ -16,7 +16,7 @@ use std::time::{Duration, Instant}; use misc::{module_and_line, timezone_to_timestamp_fn}; use types::KVFilterParameters; use types::{Format, OverflowStrategy, Severity, SourceLocation, TimeZone}; -use {Build, Config, ErrorKind, Result}; +use {Build, BuildWithCustomFormat, Config, ErrorKind, Result}; /// A logger builder which build loggers that write log records to the specified file. /// @@ -197,9 +197,23 @@ impl Build for FileLoggerBuilder { Ok(logger) } } +impl BuildWithCustomFormat for FileLoggerBuilder { + type Decorator = PlainDecorator; + + fn build_with_custom_format(&self, f: F) -> Result + where + F: FnOnce(Self::Decorator) -> Result, + D: Drain + Send + 'static, + D::Err: Debug, + { + let decorator = PlainDecorator::new(self.appender.clone()); + let drain = track!(f(decorator))?; + Ok(self.build_with_drain(drain)) + } +} #[derive(Debug)] -struct FileAppender { +pub struct FileAppender { path: PathBuf, file: Option>, truncate: bool, diff --git a/src/lib.rs b/src/lib.rs index d48c827..c584396 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,7 +64,7 @@ extern crate tempfile; extern crate trackable; extern crate regex; -pub use build::{Build, LoggerBuilder}; +pub use build::{Build, BuildWithCustomFormat, LoggerBuilder}; pub use config::{Config, LoggerConfig}; pub use error::{Error, ErrorKind}; pub use misc::set_stdlog_logger; diff --git a/src/terminal.rs b/src/terminal.rs index 8070e43..9e1a0a7 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -9,7 +9,7 @@ use std::io; use misc::{module_and_line, timezone_to_timestamp_fn}; use types::KVFilterParameters; use types::{Format, OverflowStrategy, Severity, SourceLocation, TimeZone}; -use {Build, Config, Result}; +use {Build, BuildWithCustomFormat, Config, Result}; /// A logger builder which build loggers that output log records to the terminal. /// @@ -151,6 +151,20 @@ impl Build for TerminalLoggerBuilder { Ok(logger) } } +impl BuildWithCustomFormat for TerminalLoggerBuilder { + type Decorator = Decorator; + + fn build_with_custom_format(&self, f: F) -> Result + where + F: FnOnce(Self::Decorator) -> Result, + D: Drain + Send + 'static, + D::Err: Debug, + { + let decorator = self.destination.to_decorator(); + let drain = track!(f(decorator))?; + Ok(self.build_with_drain(drain)) + } +} /// The destination to which log records will be outputted. /// @@ -192,7 +206,7 @@ impl Destination { } } -enum Decorator { +pub enum Decorator { Term(TermDecorator), PlainStdout(PlainDecorator), PlainStderr(PlainDecorator), From b96e68aec3e0d48052fd396f09892e7e736d4adf Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sat, 27 Jan 2024 10:33:05 +0900 Subject: [PATCH 2/2] Add {File,Terminal}LoggerDecorator --- src/build.rs | 3 +++ src/file.rs | 23 ++++++++++++++++++++--- src/terminal.rs | 23 ++++++++++++++++++++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/build.rs b/src/build.rs index e55ed35..b6121ad 100644 --- a/src/build.rs +++ b/src/build.rs @@ -22,9 +22,12 @@ pub trait Build { fn build(&self) -> Result; } +/// This trait allows to build a logger instance with a custom format (i.e., [`Drain`]}. pub trait BuildWithCustomFormat { + /// [`Decorator`] type generated by the logger builder. type Decorator: Decorator; + /// Builds a logger with a custom format. fn build_with_custom_format(&self, f: F) -> Result where F: FnOnce(Self::Decorator) -> Result, diff --git a/src/file.rs b/src/file.rs index 058cc4a..482a5d3 100644 --- a/src/file.rs +++ b/src/file.rs @@ -179,7 +179,7 @@ impl Build for FileLoggerBuilder { } } impl BuildWithCustomFormat for FileLoggerBuilder { - type Decorator = PlainDecorator; + type Decorator = FileLoggerDecorator; fn build_with_custom_format(&self, f: F) -> Result where @@ -187,14 +187,31 @@ impl BuildWithCustomFormat for FileLoggerBuilder { D: Drain + Send + 'static, D::Err: Debug, { - let decorator = PlainDecorator::new(self.appender.clone()); + let decorator = FileLoggerDecorator(PlainDecorator::new(self.appender.clone())); let drain = track!(f(decorator))?; Ok(self.common.build_with_drain(drain)) } } +/// [`slog_term::Decorator`] implementation for [`FileLoggerBuilder`]. +pub struct FileLoggerDecorator(PlainDecorator); + +impl slog_term::Decorator for FileLoggerDecorator { + fn with_record( + &self, + record: &slog::Record, + logger_values: &slog::OwnedKVList, + f: F, + ) -> io::Result<()> + where + F: FnOnce(&mut dyn slog_term::RecordDecorator) -> io::Result<()>, + { + self.0.with_record(record, logger_values, f) + } +} + #[derive(Debug)] -pub struct FileAppender { +struct FileAppender { path: PathBuf, file: Option>, truncate: bool, diff --git a/src/terminal.rs b/src/terminal.rs index 0f0b586..73a79dc 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -121,7 +121,7 @@ impl Build for TerminalLoggerBuilder { } } impl BuildWithCustomFormat for TerminalLoggerBuilder { - type Decorator = Decorator; + type Decorator = TerminalLoggerDecorator; fn build_with_custom_format(&self, f: F) -> Result where @@ -129,12 +129,29 @@ impl BuildWithCustomFormat for TerminalLoggerBuilder { D: Drain + Send + 'static, D::Err: Debug, { - let decorator = self.destination.to_decorator(); + let decorator = TerminalLoggerDecorator(self.destination.to_decorator()); let drain = track!(f(decorator))?; Ok(self.common.build_with_drain(drain)) } } +/// [`slog_term::Decorator`] implementation for [`TerminalLoggerBuilder`]. +pub struct TerminalLoggerDecorator(Decorator); + +impl slog_term::Decorator for TerminalLoggerDecorator { + fn with_record( + &self, + record: &slog::Record, + logger_values: &slog::OwnedKVList, + f: F, + ) -> io::Result<()> + where + F: FnOnce(&mut dyn slog_term::RecordDecorator) -> io::Result<()>, + { + self.0.with_record(record, logger_values, f) + } +} + /// The destination to which log records will be outputted. /// /// # Examples @@ -171,7 +188,7 @@ impl Destination { } } -pub enum Decorator { +enum Decorator { Term(TermDecorator), PlainStdout(PlainDecorator), PlainStderr(PlainDecorator),