1use std::fs::OpenOptions;
2use std::io::Write;
3use std::sync::{Arc, Mutex};
4
5pub struct FileLogger {
7 file: Arc<Mutex<std::fs::File>>,
8}
9
10impl FileLogger {
11 pub fn new(path: impl AsRef<std::path::Path>) -> std::io::Result<Self> {
13 let file = OpenOptions::new().create(true).append(true).open(path)?;
14
15 Ok(Self {
16 file: Arc::new(Mutex::new(file)),
17 })
18 }
19
20 pub fn log(&self, message: impl AsRef<str>) {
22 if let Ok(mut file) = self.file.lock() {
23 let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
24 let _ = writeln!(file, "[{}] {}", timestamp, message.as_ref());
25 }
26 }
27
28 pub fn log_level(&self, level: &str, message: impl AsRef<str>) {
30 if let Ok(mut file) = self.file.lock() {
31 let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
32 let _ = writeln!(file, "[{}] [{}] {}", timestamp, level, message.as_ref());
33 }
34 }
35}
36
37impl Clone for FileLogger {
38 fn clone(&self) -> Self {
39 Self {
40 file: Arc::clone(&self.file),
41 }
42 }
43}