ma_core/config/
logging.rs1use tracing_subscriber::{
13 filter::LevelFilter, fmt, layer::SubscriberExt, prelude::*, util::SubscriberInitExt,
14};
15
16use crate::error::{Error, Result};
17
18use super::Config;
19
20impl Config {
21 pub fn init_logging(&self) -> Result<()> {
31 let file_level: LevelFilter = self
32 .log_level
33 .parse()
34 .map_err(|_| Error::Config(format!("invalid log_level: {}", self.log_level)))?;
35
36 let stdout_level: LevelFilter = self.log_level_stdout.parse().map_err(|_| {
37 Error::Config(format!(
38 "invalid log_level_stdout: {}",
39 self.log_level_stdout
40 ))
41 })?;
42
43 let log_path = self.effective_log_file()?;
44
45 if let Some(parent) = log_path.parent() {
47 std::fs::create_dir_all(parent).map_err(|e| {
48 Error::Config(format!(
49 "failed to create log directory {}: {e}",
50 parent.display()
51 ))
52 })?;
53 }
54
55 let log_file = std::fs::OpenOptions::new()
56 .create(true)
57 .append(true)
58 .open(&log_path)
59 .map_err(|e| {
60 Error::Config(format!(
61 "failed to open log file {}: {e}",
62 log_path.display()
63 ))
64 })?;
65
66 let file_layer = fmt::layer()
67 .with_writer(std::sync::Mutex::new(log_file))
68 .with_ansi(false)
69 .with_filter(file_level);
70
71 let stdout_layer = fmt::layer()
72 .with_writer(std::io::stdout)
73 .with_filter(stdout_level);
74
75 tracing_subscriber::registry()
76 .with(file_layer)
77 .with(stdout_layer)
78 .try_init()
79 .map_err(|e| Error::Config(format!("failed to initialise logging: {e}")))?;
80
81 Ok(())
82 }
83}