use std::fs::{self, File, OpenOptions};
use std::io::{self, Write};
use std::path::PathBuf;
pub struct RotatingFileWriter {
file: File,
path: PathBuf,
bytes_written: u64,
max_bytes: u64,
}
impl RotatingFileWriter {
pub fn new(path: PathBuf, file: File, max_bytes: u64) -> Self {
let current_size = fs::metadata(&path).map(|m| m.len()).unwrap_or(0);
Self {
file,
path,
bytes_written: current_size,
max_bytes,
}
}
fn rotate(&mut self) -> io::Result<()> {
let backup = self.path.with_extension("log.old");
let _ = fs::remove_file(&backup); fs::rename(&self.path, &backup)?;
self.file = OpenOptions::new()
.create(true)
.append(true)
.open(&self.path)?;
self.bytes_written = 0;
Ok(())
}
}
impl Write for RotatingFileWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let n = self.file.write(buf)?;
self.bytes_written += n as u64;
if self.bytes_written >= self.max_bytes {
if let Err(e) = self.rotate() {
eprintln!("Warning: log rotation failed: {}", e);
}
}
Ok(n)
}
fn flush(&mut self) -> io::Result<()> {
self.file.flush()
}
}