Skip to content

Commit

Permalink
Merge pull request #46 from getAlby/log-rotate
Browse files Browse the repository at this point in the history
Implement daily log file rotation
  • Loading branch information
rolznz authored Aug 15, 2024
2 parents df42713 + 7bb90ca commit 955b763
Showing 1 changed file with 50 additions and 30 deletions.
80 changes: 50 additions & 30 deletions src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,67 @@ use chrono::Utc;
use std::fs;
#[cfg(not(target_os = "windows"))]
use std::os::unix::fs::symlink;
use std::path::Path;
use std::path::{Path, PathBuf};

pub(crate) struct FilesystemLogger {
file_path: String,
log_dir: String,
level: Level,
}

impl FilesystemLogger {
pub(crate) fn new(log_dir: String, level: Level) -> Result<Self, ()> {
let log_file_name =
format!("ldk_node_{}.log", chrono::offset::Local::now().format("%Y_%m_%d"));
let log_file_path = format!("{}/{}", log_dir, log_file_name);
fs::create_dir_all(&log_dir).expect("Failed to create log parent directory");

if let Some(parent_dir) = Path::new(&log_file_path).parent() {
fs::create_dir_all(parent_dir).expect("Failed to create log parent directory");
Ok(Self { log_dir, level })
}

// make sure the file exists, so that the symlink has something to point to.
fs::OpenOptions::new()
.create(true)
.append(true)
.open(log_file_path.clone())
.map_err(|e| eprintln!("ERROR: Failed to open log file: {}", e))?;
fn make_log_file_name() -> String {
format!("ldk_node_{}.log", chrono::offset::Local::now().format("%Y_%m_%d"))
}

#[cfg(not(target_os = "windows"))]
{
// Create a symlink to the current log file, with prior cleanup
let log_file_symlink = parent_dir.join("ldk_node_latest.log");
if log_file_symlink.as_path().is_symlink() {
fs::remove_file(&log_file_symlink).map_err(|e| {
eprintln!("ERROR: Failed to remove log file symlink: {}", e)
})?;
}
symlink(&log_file_name, &log_file_symlink)
.map_err(|e| eprintln!("ERROR: Failed to create log file symlink: {}", e))?;
fn make_log_file_symlink<D: AsRef<Path>, F: AsRef<Path>>(
log_dir: D, log_file_name: F,
) -> Result<(), ()> {
#[cfg(not(target_os = "windows"))]
{
// Create a symlink to the current log file, with prior cleanup
let log_file_symlink = log_dir.as_ref().join("ldk_node_latest.log");
if log_file_symlink.as_path().is_symlink() {
fs::remove_file(&log_file_symlink)
.map_err(|e| eprintln!("ERROR: Failed to remove log file symlink: {}", e))?;
}
symlink(&log_file_name, &log_file_symlink)
.map_err(|e| eprintln!("ERROR: Failed to create log file symlink: {}", e))?;
}

Ok(())
}

fn log_file_path(&self) -> PathBuf {
PathBuf::from(format!("{}/{}", self.log_dir, FilesystemLogger::make_log_file_name()))
}

fn open_log_file(&self) -> Result<fs::File, ()> {
let log_path = self.log_file_path();
let is_new_file = log_path.try_exists().and_then(|e| Ok(!e)).unwrap_or(false);

let ret = fs::OpenOptions::new()
.create(true)
.append(true)
.open(&log_path)
.map_err(|e| eprintln!("ERROR: Failed to open log file: {}", e))?;

if is_new_file {
// Do not check for errors; in concurrent scenarios, this is not
// unlikely to fail. The concurrent thread should be able to finish
// the operation.
let _ = FilesystemLogger::make_log_file_symlink(
&self.log_dir,
log_path.file_name().unwrap(),
);
}

Ok(Self { file_path: log_file_path, level })
Ok(ret)
}
}
impl Logger for FilesystemLogger {
Expand All @@ -63,12 +86,9 @@ impl Logger for FilesystemLogger {
record.line,
raw_log
);
fs::OpenOptions::new()
.create(true)
.append(true)
.open(self.file_path.clone())
self.open_log_file()
.expect("Failed to open log file")
.write_all(log.as_bytes())
.expect("Failed to write to log file")
.expect("Failed to write to log file");
}
}

0 comments on commit 955b763

Please sign in to comment.