context_creator/
logging.rs

1//! Logging configuration and initialization
2
3use anyhow::Result;
4use tracing::Level;
5use tracing_subscriber::{fmt, EnvFilter};
6
7use crate::{cli::LogFormat, Config};
8
9/// Initialize the logging system based on configuration
10pub fn init_logging(config: &Config) -> Result<()> {
11    // Determine the log level based on flags
12    let log_level = get_log_level(config.verbose, config.quiet, config.progress);
13
14    // Create the base subscriber
15    let builder = fmt::Subscriber::builder()
16        .with_target(false)
17        .with_thread_ids(false)
18        .with_thread_names(false)
19        .with_writer(std::io::stderr);
20
21    // Check if RUST_LOG is set
22    let env_filter = if std::env::var("RUST_LOG").is_ok() {
23        // Use RUST_LOG if set
24        EnvFilter::from_default_env()
25    } else {
26        // Otherwise use our level
27        EnvFilter::new(format!("{log_level}"))
28    };
29
30    match config.log_format {
31        LogFormat::Json => {
32            // JSON format for structured logging
33            builder.json().with_env_filter(env_filter).try_init().ok();
34        }
35        LogFormat::Plain => {
36            // Human-readable format
37            builder.with_env_filter(env_filter).try_init().ok();
38        }
39    }
40
41    Ok(())
42}
43
44/// Get the appropriate log level based on verbose and quiet flags
45pub fn get_log_level(verbose: u8, quiet: bool, progress: bool) -> Level {
46    if quiet {
47        Level::ERROR
48    } else {
49        match verbose {
50            0 => {
51                // If progress is enabled, show INFO level to display progress messages
52                if progress {
53                    Level::INFO
54                } else {
55                    Level::WARN // Default: show warnings and errors
56                }
57            }
58            1 => Level::DEBUG, // -v: show debug logs
59            _ => Level::TRACE, // -vv or more: show trace logs
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_log_level_selection() {
70        // Test quiet mode
71        assert_eq!(get_log_level(0, true, false), Level::ERROR);
72        assert_eq!(get_log_level(1, true, false), Level::ERROR);
73        assert_eq!(get_log_level(2, true, false), Level::ERROR);
74
75        // Test verbose levels
76        assert_eq!(get_log_level(0, false, false), Level::WARN);
77        assert_eq!(get_log_level(1, false, false), Level::DEBUG);
78        assert_eq!(get_log_level(2, false, false), Level::TRACE);
79        assert_eq!(get_log_level(3, false, false), Level::TRACE);
80
81        // Test progress mode
82        assert_eq!(get_log_level(0, false, true), Level::INFO);
83        assert_eq!(get_log_level(0, true, true), Level::ERROR); // quiet overrides progress
84    }
85}