Skip to main content

baichun_framework_logger/appender/
file.rs

1use std::{
2    fs::{self, File},
3    io::{BufWriter, Write},
4    path::PathBuf,
5    sync::Arc,
6};
7
8use parking_lot::Mutex;
9
10use crate::{config::LogLevel, error::Result};
11
12use super::LogAppender;
13
14/// 文件追加器
15#[derive(Debug)]
16pub struct FileAppender {
17    /// 文件路径
18    path: PathBuf,
19    /// 写入器
20    writer: Arc<Mutex<BufWriter<File>>>,
21}
22
23impl FileAppender {
24    /// 创建文件追加器
25    pub fn new(path: PathBuf) -> Result<Self> {
26        // 创建目录
27        if let Some(parent) = path.parent() {
28            fs::create_dir_all(parent)?;
29        }
30
31        // 打开文件
32        let file = std::fs::OpenOptions::new()
33            .create(true)
34            .append(true)
35            .open(&path)?;
36
37        Ok(Self {
38            path,
39            writer: Arc::new(Mutex::new(BufWriter::new(file))),
40        })
41    }
42
43    /// 获取文件路径
44    pub fn path(&self) -> &PathBuf {
45        &self.path
46    }
47}
48
49impl LogAppender for FileAppender {
50    fn write(&self, _level: LogLevel, message: &str) -> Result<()> {
51        let mut writer = self.writer.lock();
52        writer.write_all(message.as_bytes())?;
53        writer.write_all(b"\n")?;
54        Ok(())
55    }
56
57    fn flush(&self) -> Result<()> {
58        let mut writer = self.writer.lock();
59        writer.flush()?;
60        Ok(())
61    }
62}
63
64impl Clone for FileAppender {
65    fn clone(&self) -> Self {
66        Self {
67            path: self.path.clone(),
68            writer: Arc::clone(&self.writer),
69        }
70    }
71}