Skip to main content

pimalaya_cli/
log.rs

1//! Logger initialization from the shared log flags.
2
3use std::fs::OpenOptions;
4
5use anyhow::Result;
6use env_logger::{Builder, Target};
7
8use crate::clap::args::LogFlags;
9
10/// Initializes the process logger from the shared log flags.
11pub struct Logger;
12
13impl Logger {
14    /// Initialises `env_logger` from `log`. When [`LogFlags::file`]
15    /// is set the log target is opened in append mode (creating it
16    /// if missing) and used for output; otherwise logs go to stderr
17    /// as usual.
18    ///
19    /// Opening the log file is fallible: if the caller asked for one
20    /// but we cannot create or open it, the error is returned rather
21    /// than silently falling back to stderr and polluting interactive
22    /// prompts.
23    pub fn try_init(log: &LogFlags) -> Result<()> {
24        let mut builder = Builder::new();
25
26        match log.level {
27            Some(level) => {
28                // NOTE: explicit `--log-level` overrides any `RUST_LOG`.
29                builder.filter_level(level.into());
30            }
31            None => {
32                // NOTE: defer to `RUST_LOG` (if unset, env_logger filters
33                // everything, same as `--log-level off`).
34                builder.parse_default_env();
35            }
36        }
37
38        if let Some(path) = &log.file {
39            let file = OpenOptions::new().create(true).append(true).open(path)?;
40            builder.target(Target::Pipe(Box::new(file)));
41        }
42
43        builder.try_init()?;
44        Ok(())
45    }
46}