graph_simulation/utils/
logger.rs

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