Skip to content

Commit

Permalink
Add custom logger
Browse files Browse the repository at this point in the history
  • Loading branch information
tjardoo committed Sep 11, 2024
1 parent 614e2bc commit b213b25
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ log = { version = "0.4", features = ["std"] }
chrono = "0.4"

[workspace]
members = ["examples/console", "examples/stdout"]
members = ["examples/console", "examples/custom", "examples/stack", "examples/stdout"]
63 changes: 56 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

Ftail is simple logging implementation for the `log` crate with support for multiple drivers.

- Stdout (standard output logging)
- Console (formatted output logging)
- Daily (daily log rotation)
- Single (single log file)
- [Stdout (standard output logging)](#stdout)
- [Console (formatted output logging)](#console)
- [Single (single log file)](#single)
- [Daily (daily log rotation)](#daily)
- [Custom (custom log driver)](#custom)

## Usage

```rust
use ftail::Ftail;
use log::LevelFilter;

Ftail::new()
.add_driver(ConsoleLogger::new(), log::LevelFilter::Trace)
.stdout(LevelFilter::Trace)
.init()?;

log::debug!("This is a debug message");
Expand All @@ -26,7 +28,13 @@ log::info!("This is an info message");

Logs to the standard output.

```sh
```rust
Ftail::new()
.stdout(LevelFilter::Trace)
.init()?;
```

```log
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
Expand All @@ -38,7 +46,13 @@ Logs to the standard output.

Logs to the standard output with formatted and colored output.

```sh
```rust
Ftail::new()
.console(LevelFilter::Trace)
.init()?;
```

```log
2024-09-10 14:42:21 · TRACE
This is a trace message
examples\console\src/main.rs:8
Expand All @@ -59,3 +73,38 @@ examples\console\src/main.rs:14
This is an error
examples\console\src/main.rs:16
```

### Single

TODO

### Daily

TODO

### Custom

Create your own log driver.

```rust
Ftail::new()
.custom(Box::new(Box::new(CustomLogger {})), LevelFilter::Debug)
.init()?;

// the custom logger implementation
struct CustomLogger {}

impl Log for CustomLogger {
fn enabled(&self, _metadata: &log::Metadata) -> bool {
true
}

fn log(&self, record: &log::Record) {
let time = chrono::Local::now().format("%H:%M:%S").to_string();

println!("{} {} {}", time, record.level(), record.args());
}

fn flush(&self) {}
}
```
7 changes: 3 additions & 4 deletions examples/console/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use ftail::{drivers::console::ConsoleLogger, Ftail};
use ftail::Ftail;
use log::LevelFilter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Ftail::new()
.add_driver(ConsoleLogger::new(), log::LevelFilter::Trace)
.init()?;
Ftail::new().console(LevelFilter::Trace).init()?;

log::trace!("This is a trace message");

Expand Down
10 changes: 10 additions & 0 deletions examples/custom/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "custom"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
log = "0.4"
ftail = { path = "../../../ftail" }
chrono = "0.4"
36 changes: 36 additions & 0 deletions examples/custom/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use ftail::Ftail;
use log::{LevelFilter, Log};

fn main() -> Result<(), Box<dyn std::error::Error>> {
Ftail::new()
.custom(Box::new(Box::new(CustomLogger {})), LevelFilter::Debug)
.init()?;

log::trace!("This is a trace message");

log::debug!("This is a debug message");

log::info!(target: "foo", "bar");

log::warn!("This is a warning");

log::error!("This is an error");

Ok(())
}

struct CustomLogger {}

impl Log for CustomLogger {
fn enabled(&self, _metadata: &log::Metadata) -> bool {
true
}

fn log(&self, record: &log::Record) {
let time = chrono::Local::now().format("%H:%M:%S").to_string();

println!("{} {} {}", time, record.level(), record.args());
}

fn flush(&self) {}
}
9 changes: 9 additions & 0 deletions examples/stack/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "stack"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
log = "0.4"
ftail = { path = "../../../ftail" }
21 changes: 21 additions & 0 deletions examples/stack/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use ftail::Ftail;
use log::LevelFilter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Ftail::new()
.stdout(LevelFilter::Trace)
.console(LevelFilter::Trace)
.init()?;

log::trace!("This is a trace message");

log::debug!("This is a debug message");

log::info!(target: "foo", "bar");

log::warn!("This is a warning");

log::error!("This is an error");

Ok(())
}
7 changes: 3 additions & 4 deletions examples/stdout/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use ftail::{drivers::stdout::StdOutLogger, Ftail};
use ftail::Ftail;
use log::LevelFilter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Ftail::new()
.add_driver(StdOutLogger::new(), log::LevelFilter::Trace)
.init()?;
Ftail::new().stdout(LevelFilter::Trace).init()?;

log::trace!("This is a trace message");

Expand Down
10 changes: 0 additions & 10 deletions src/drivers/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,12 @@ use crate::ansi_escape::TextStyling;

pub struct ConsoleLogger {}

impl ConsoleLogger {
pub fn new() -> Box<ConsoleLogger> {
Box::new(ConsoleLogger {})
}
}

impl Log for ConsoleLogger {
fn enabled(&self, _metadata: &log::Metadata) -> bool {
true
}

fn log(&self, record: &log::Record) {
if !self.enabled(record.metadata()) {
return;
}

let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

let level = match record.level() {
Expand Down
10 changes: 0 additions & 10 deletions src/drivers/stdout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,12 @@ use log::Log;

pub struct StdOutLogger {}

impl StdOutLogger {
pub fn new() -> Box<StdOutLogger> {
Box::new(StdOutLogger {})
}
}

impl Log for StdOutLogger {
fn enabled(&self, _metadata: &log::Metadata) -> bool {
true
}

fn log(&self, record: &log::Record) {
if !self.enabled(record.metadata()) {
return;
}

let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

println!(
Expand Down
20 changes: 20 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::fmt::Display;

use log::SetLoggerError;

#[derive(Debug)]
pub enum FtailError {
SetLoggerError(SetLoggerError),
DuplicatedDriver(String),
}

impl std::error::Error for FtailError {}

impl Display for FtailError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FtailError::SetLoggerError(e) => write!(f, "Error setting logger: {}", e),
FtailError::DuplicatedDriver(driver) => write!(f, "Duplicated driver: {}", driver),
}
}
}
23 changes: 19 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use drivers::{console::ConsoleLogger, stdout::StdOutLogger};
use error::FtailError;
use log::Log;

mod ansi_escape;
pub mod drivers;
pub mod error;

pub struct LogDriver {
pub(crate) struct LogDriver {
driver: Box<dyn Log>,
level: log::LevelFilter,
}
Expand All @@ -19,15 +22,27 @@ impl Ftail {
}
}

pub fn add_driver(mut self, driver: Box<dyn Log>, level: log::LevelFilter) -> Self {
fn add_driver(mut self, driver: Box<dyn Log>, level: log::LevelFilter) -> Self {
self.drivers.push(LogDriver { driver, level });

self
}

pub fn init(self) -> Result<(), log::SetLoggerError> {
pub fn stdout(self, level: log::LevelFilter) -> Self {
self.add_driver(Box::new(Box::new(StdOutLogger {})), level)
}

pub fn console(self, level: log::LevelFilter) -> Self {
self.add_driver(Box::new(Box::new(ConsoleLogger {})), level)
}

pub fn custom(self, driver: Box<dyn Log>, level: log::LevelFilter) -> Self {
self.add_driver(Box::new(driver), level)
}

pub fn init(self) -> Result<(), FtailError> {
log::set_max_level(log::LevelFilter::Trace);
log::set_boxed_logger(Box::new(self))
log::set_boxed_logger(Box::new(self)).map_err(FtailError::SetLoggerError)
}
}

Expand Down

0 comments on commit b213b25

Please sign in to comment.