use std::{fs::OpenOptions, net::SocketAddr, sync::Arc};
use chrono::Utc;
use tokio::{fs::File, io::AsyncWriteExt, sync::Mutex};
use crate::http::{requests::HttpRequest, responses::HttpResponse};
#[allow(dead_code)] pub struct Logger {
log_file: Option<Arc<Mutex<File>>>,
level: u8,
debug: bool,
}
impl Logger {
pub fn new(log_file: Option<String>, level: Option<u8>, debug: Option<bool>) -> Self {
let log_file = if let Some(log_file_path) = log_file {
let file = OpenOptions::new()
.create(true)
.append(true)
.open(log_file_path)
.unwrap();
Some(Arc::new(Mutex::new(File::from_std(file))))
} else {
None
};
Self {
log_file,
level: level.or(Some(1)).unwrap(),
debug: debug.or(Some(false)).unwrap(),
}
}
pub fn write_req_res(
&self,
request: &HttpRequest,
response: &HttpResponse,
socket_addr: &SocketAddr,
) {
let response_format = format!(
"{} | {} {} | {} {}\r\n",
Utc::now().to_rfc2822(),
socket_addr,
request.uri,
response.status as u16,
response.status.to_string()
);
if self.debug {
println!("{response_format}");
}
if let Some(log_file) = &self.log_file {
let log_file = log_file.clone();
tokio::spawn(async move {
let mut f = log_file.lock().await;
let _ = f.write_all(response_format.as_bytes()).await;
});
}
}
}