balius_runtime/logging/
file.rs1use std::{
3 collections::BTreeMap,
4 fs::{File, OpenOptions},
5 io::{self, Write}, path::PathBuf,
7};
8
9use crate::wit::balius::app::logging as wit;
10
11use super::{level_to_string, LoggerProvider};
12
13pub struct FileLogger {
15 files: BTreeMap<String, File>,
16 folder: PathBuf,
17}
18
19impl FileLogger {
20 pub fn try_new(folder: Option<PathBuf>) -> io::Result<Self> {
25 let folder = folder.unwrap_or(std::env::current_dir()?);
26
27 std::fs::create_dir_all(&folder)?; Ok(FileLogger {
31 files: BTreeMap::new(),
32 folder,
33 })
34 }
35}
36
37#[async_trait::async_trait]
38impl LoggerProvider for FileLogger {
39 async fn log(&mut self, worker_id: &str, level: wit::Level, context: String, message: String) {
40 let mut file = match self.files.get(worker_id) {
41 Some(file) => file,
42 None => {
43 let Ok(file) = OpenOptions::new()
44 .create(true)
45 .append(true)
46 .open(self.folder.join(format!("{worker_id}.log")))
47 else {
48 return;
49 };
50 self.files.entry(worker_id.to_string()).or_insert(file)
51 }
52 };
53 let _ = file.write(
54 format!(
55 "{}: {} - {} - {}\n",
56 chrono::Utc::now().to_rfc3339(),
57 level_to_string(&level),
58 context,
59 message
60 )
61 .as_bytes(),
62 );
63 }
64}