1use crate::log::Log;
2use crate::sink::Sink;
3use anyhow::Result;
4use async_trait::async_trait;
5use std::path::PathBuf;
6use tokio::fs::{File, OpenOptions};
7use tokio::io::AsyncWriteExt;
8use tokio::task;
9
10pub(crate) struct FileSink {
11 file: File,
12}
13
14impl FileSink {
15 #[allow(dead_code)]
16 pub(crate) async fn new(file: PathBuf) -> Result<Self> {
17 let f = OpenOptions::new()
18 .write(true)
19 .truncate(true)
20 .create(true)
21 .open(file)
22 .await?;
23 Ok(Self { file: f })
24 }
25}
26
27#[async_trait]
28impl Sink for FileSink {
29 async fn write(&self, log: Log) {
30 let s = format!(
31 "{} {:11} {:>5} {:<5} {} {} {}\n",
32 log.date, log.time, log.pid, log.tid, log.level, log.tag, log.message
33 );
34 let file = self.file.try_clone().await;
35 task::spawn(async move {
36 if let Ok(mut file) = file {
37 if let Ok(_) = file.write_all(s.as_bytes()).await {}
38 }
39 });
40 }
41}