use std::fmt::Arguments;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::{self, Write};
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug)]
pub enum LogLevel {
Fatal,
Warning,
Info,
Debug,
}
pub struct Logger {
log_fp: File,
}
impl Logger {
pub fn new(filename: &str) -> io::Result<Logger> {
let log_fp = OpenOptions::new()
.create(true)
.append(true)
.open(filename)?;
Ok(Logger { log_fp })
}
pub fn write(
&mut self,
level: LogLevel,
source_filename: &str,
line: u32,
args: Arguments,
) -> io::Result<()> {
log_write_fmt(&mut self.log_fp, level, source_filename, line, args)
}
}
impl Drop for Logger {
fn drop(&mut self) {
let _ = self.log_fp.flush();
}
}
fn log_write_fmt(
log_fp: &mut File,
level: LogLevel,
source_filename: &str,
line: u32,
args: Arguments,
) -> io::Result<()> {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
let datetime = format!("{}", now);
let mut msg_buf = String::new();
std::fmt::write(&mut msg_buf, args).ok();
let entry = format!(
"{:?} [{}] [{}:{}]{}\n",
level, datetime, source_filename, line, msg_buf
);
log_fp.write_all(entry.as_bytes())
}