use std::fs;
use chrono::Local;
use chrono::Utc;
#[derive(Debug)]
pub struct Logger {
pub logger_name: String,
pub file_log: Option<String>,
pub use_utc: bool,
}
impl Logger {
pub fn new(logger_name: String, file_log: Option<String>, use_utc: bool) -> Self {
if let Some(file) = file_log.clone() {
let mut file_log_content = String::new();
if std::path::Path::new(&file.clone()).exists() {
file_log_content = fs::read_to_string(file.clone())
.unwrap_or_else(|_| panic!("Could not read log file `{}`", file));
}
fs::write(file.clone(), file_log_content.as_bytes())
.unwrap_or_else(|_| panic!("Could not create log file `{}`", file));
}
Logger {
logger_name,
file_log,
use_utc,
}
}
pub fn log<T: std::fmt::Display>(&self, msg: T) {
let to_log = format!(
"{} - [{:?}]: {}",
self.logger_name,
{
if self.use_utc {
Utc::now().to_string()
} else {
Local::now().to_string()
}
},
msg
);
println!("{}", to_log);
}
pub fn log_to_file<T: std::fmt::Display>(&self, msg: T) {
if let Some(file_log) = &self.file_log {
let file_log_content = fs::read_to_string(file_log.clone())
.unwrap_or_else(|_| panic!("Could not read log file `{}`", file_log.clone()));
fs::write(
&file_log.clone(),
(file_log_content
+ "\n"
+ &format!(
"{} - [{:?}]: {}",
self.logger_name,
{
if self.use_utc {
Utc::now().to_string()
} else {
Local::now().to_string()
}
},
msg
))
.as_bytes(),
)
.unwrap_or_else(|_| panic!("Could not create log file `{}`", file_log.clone()));
} else {
panic!("Log file not provided.");
}
}
pub fn log_and_log_to_file(&self, msg: String) {
self.log(msg.clone());
self.log_to_file(msg);
}
pub fn error<T: std::fmt::Display>(&self, msg: T) {
let to_log = format!(
"ERROR: {} - [{:?}]: {}",
self.logger_name,
{
if self.use_utc {
Utc::now().to_string()
} else {
Local::now().to_string()
}
},
msg
);
println!("{}", to_log);
}
pub fn error_to_file<T: std::fmt::Display>(&self, msg: T) {
if let Some(file_log) = &self.file_log {
let file_log_content = fs::read_to_string(file_log.clone())
.unwrap_or_else(|_| panic!("Could not read log file `{}`", file_log.clone()));
fs::write(
&file_log.clone(),
(file_log_content
+ "\n"
+ &format!(
"ERROR: {} - [{:?}]: {}",
self.logger_name,
{
if self.use_utc {
Utc::now().to_string()
} else {
Local::now().to_string()
}
},
msg
))
.as_bytes(),
)
.unwrap_or_else(|_| panic!("Could not create log file `{}`", file_log.clone()));
} else {
panic!("Log file not provided.");
}
}
pub fn error_and_error_to_file(&self, msg: String) {
self.error(msg.clone());
self.error_to_file(msg);
}
pub fn error_and_stop<T: std::fmt::Display>(&self, msg: T) {
let to_log = format!(
"ERROR: {} - [{:?}]: {}",
self.logger_name,
{
if self.use_utc {
Utc::now().to_string()
} else {
Local::now().to_string()
}
},
msg
);
println!("{}", to_log);
std::process::exit(1);
}
pub fn error_and_stop_to_file<T: std::fmt::Display>(&self, msg: T) {
if let Some(file_log) = &self.file_log {
let file_log_content = fs::read_to_string(file_log.clone())
.unwrap_or_else(|_| panic!("Could not read log file `{}`", file_log.clone()));
fs::write(
&file_log.clone(),
(file_log_content
+ "\n"
+ &format!(
"ERROR: {} - [{:?}]: {}",
self.logger_name,
{
if self.use_utc {
Utc::now().to_string()
} else {
Local::now().to_string()
}
},
msg
))
.as_bytes(),
)
.unwrap_or_else(|_| panic!("Could not create log file `{}`", file_log.clone()));
std::process::exit(1);
} else {
panic!("Log file not provided.");
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
use crate::Logger;
let my_logger = Logger::new("My Logger".to_string(), Some("log.txt".to_string()), true);
my_logger.log("Hello world");
my_logger.log_to_file("Hello world 123");
my_logger.log_and_to_file("He ate my cereals");
}
}