use chrono::prelude::*;
use std::sync::Mutex;
use std::fs::File;
use std::io::{Write, self};
#[derive(Debug, PartialEq)]
pub enum LogLevel{
DEBUG,
INFO,
WARNING,
ERROR,
FATAL,
}
pub struct Logger{
output_lock: Mutex::<std::io::Stdout>,
file_lock: Option<Mutex::<File>>,
}
impl Logger {
pub fn new(file_path: &str) -> Self{
let mut file_lock = None;
if file_path != "" {
file_lock = Some(Mutex::new(File::create(file_path).unwrap()));
}
Logger{
output_lock: Mutex::new(io::stdout()),
file_lock: file_lock,
}
}
pub async fn log(&mut self, log_level: LogLevel, message: &str) -> std::io::Result<()>{
let self_clone = self;
let mut output_log = self_clone.output_lock.lock().unwrap();
let formatted_output = format!("{} {:?} {}", Local::now(), log_level, message);
output_log.write_all(formatted_output.as_bytes()).unwrap();
output_log.write_all(b"\n").unwrap();
drop(output_log);
Ok(())
}
pub async fn log_to_file(&mut self, log_level: LogLevel, message: &str) -> std::io::Result<()>{
let file_lock = self.file_lock.as_mut().unwrap();
let formatted_output = format!("{} {:?} {}", Local::now(), log_level, message);
file_lock.lock().unwrap().write_all(formatted_output.as_bytes()).unwrap();
Ok(())
}
}