baichun_framework_logger/appender/
file.rs1use 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#[derive(Debug)]
16pub struct FileAppender {
17 path: PathBuf,
19 writer: Arc<Mutex<BufWriter<File>>>,
21}
22
23impl FileAppender {
24 pub fn new(path: PathBuf) -> Result<Self> {
26 if let Some(parent) = path.parent() {
28 fs::create_dir_all(parent)?;
29 }
30
31 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 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}