graph_simulation/utils/
logger.rs

1use std::{io, fs::File, sync::{OnceLock, Mutex}};
2use env_logger::Target;
3
4// 1. 定义日志写入器(支持文件+控制台双输出)
5struct MultiWriter {
6    file: Mutex<File>,
7    stdout: io::Stdout,
8}
9
10impl io::Write for MultiWriter {
11    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
12        // 线程安全写入(加锁)
13        let mut file = self.file.lock().unwrap();
14        file.write_all(buf)?;
15        self.stdout.write_all(buf)?;
16        Ok(buf.len())
17    }
18
19    fn flush(&mut self) -> io::Result<()> {
20        let mut file = self.file.lock().unwrap();
21        file.flush()?;
22        self.stdout.flush()?;
23        Ok(())
24    }
25}
26
27// 2. 全局日志初始化器(静态单例)
28static LOGGER_INIT: OnceLock<()> = OnceLock::new();
29
30// 3. 安全的全局初始化函数
31pub fn init_global_logger_once(output_file: &'static str) {
32    LOGGER_INIT.get_or_init(|| {
33        let log_file = File::create(output_file)
34            .expect("Failed to create log file");
35        
36        let multi_writer = MultiWriter {
37            file: Mutex::new(log_file),
38            stdout: io::stdout(),
39        };
40
41        // 配置并初始化env_logger
42        env_logger::Builder::new()
43            .target(Target::Pipe(Box::new(multi_writer)))
44            .init();
45
46        log::info!("Logger initialized successfully");
47    });
48}