Skip to content

Commit

Permalink
Add daily driver
Browse files Browse the repository at this point in the history
  • Loading branch information
tjardoo committed Sep 11, 2024
1 parent b4344fe commit cdc4a3a
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ chrono = "0.4"
members = [
"examples/console",
"examples/custom",
"examples/daily",
"examples/single",
"examples/stack",
"examples/stdout",
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,18 @@ Ftail::new()

### Daily

TODO
Logs to a daily log file.

The `daily` driver takes the following parameters:

- `dir`: the directory to store the log files
- `level`: the minumum log level to log

```rust
Ftail::new()
.daily("logs", LevelFilter::Trace)
.init()?;
```

### Custom

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

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

fn main() -> Result<(), Box<dyn std::error::Error>> {
Ftail::new().daily("logs", 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 message");

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

Ok(())
}
85 changes: 85 additions & 0 deletions src/drivers/daily.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use log::Log;
use std::{
fs::File,
io::{LineWriter, Write},
sync::Mutex,
};

pub struct DailyLogger {
file: Mutex<LineWriter<File>>,
dir: String,
current_date: Mutex<String>,
}

impl DailyLogger {
pub fn new(dir: &str) -> Self {
let today = chrono::Local::now().format("%Y-%m-%d").to_string();
let path = format!("{}/{}.log", dir, today);

let file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.unwrap();

let md = std::fs::metadata(dir).unwrap();

if md.permissions().readonly() {
panic!("The logs directory `{dir}` is readonly");
}

DailyLogger {
file: Mutex::new(LineWriter::new(file)),
dir: dir.to_string(),
current_date: Mutex::new(today),
}
}

fn rotate_file_if_needed(&self) {
let today = chrono::Local::now().format("%Y-%m-%d").to_string();
let mut current_date = self.current_date.lock().unwrap();

if *current_date != today {
let path = format!("{}/{}.log", self.dir, today);

let new_file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.unwrap();

let mut file = self.file.lock().unwrap();

*file = LineWriter::new(new_file);
*current_date = today;
}
}
}

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

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 mut file = self.file.lock().unwrap();
writeln!(file, "{}", line).unwrap();
file.flush().unwrap();
}

fn flush(&self) {
self.file.lock().unwrap().flush().unwrap();
}
}
1 change: 1 addition & 0 deletions src/drivers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod console;
pub mod daily;
pub mod single;
pub mod stdout;
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use drivers::{console::ConsoleLogger, single::SingleLogger, stdout::StdOutLogger};
use drivers::{
console::ConsoleLogger, daily::DailyLogger, single::SingleLogger, stdout::StdOutLogger,
};
use error::FtailError;
use log::Log;

Expand Down Expand Up @@ -40,6 +42,10 @@ impl Ftail {
self.add_driver(Box::new(SingleLogger::new(path, append)), level)
}

pub fn daily(self, path: &str, level: log::LevelFilter) -> Self {
self.add_driver(Box::new(DailyLogger::new(path)), level)
}

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

0 comments on commit cdc4a3a

Please sign in to comment.