Skip to main content

mangofetch_core/core/
logger.rs

1use std::path::PathBuf;
2use tracing_appender::non_blocking;
3use tracing_subscriber::{fmt, prelude::*, Registry};
4
5pub fn init_logging(verbose: bool) {
6    init_logging_ext(verbose, true);
7}
8
9pub fn init_logging_ext(verbose: bool, use_stdout: bool) {
10    let log_dir = crate::core::paths::app_data_dir()
11        .map(|d| d.join("logs"))
12        .unwrap_or_else(|| PathBuf::from("logs"));
13
14    let _ = std::fs::create_dir_all(&log_dir);
15
16    let file_appender = tracing_appender::rolling::daily(&log_dir, "mangofetch.log");
17    let (non_blocking_appender, _guard) = non_blocking(file_appender);
18
19    // Keep the guard alive as long as the program runs.
20    Box::leak(Box::new(_guard));
21
22    let file_layer = fmt::layer()
23        .with_ansi(false)
24        .with_writer(non_blocking_appender);
25
26    if use_stdout {
27        let stdout_layer = fmt::layer()
28            .with_ansi(true)
29            .with_target(verbose)
30            .with_filter(if verbose {
31                tracing_subscriber::filter::LevelFilter::DEBUG
32            } else {
33                tracing_subscriber::filter::LevelFilter::INFO
34            });
35
36        let subscriber = Registry::default().with(file_layer).with(stdout_layer);
37        tracing::subscriber::set_global_default(subscriber)
38            .expect("setting default subscriber failed");
39    } else {
40        let subscriber = Registry::default().with(file_layer);
41        tracing::subscriber::set_global_default(subscriber)
42            .expect("setting default subscriber failed");
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49    use std::env;
50    use std::process::Command;
51    use uuid::Uuid;
52
53    #[test]
54    fn test_init_logging_ext_subprocess() {
55        if env::var("TEST_INIT_LOGGING_EXT").is_ok() {
56            let temp_dir = env::temp_dir().join(Uuid::new_v4().to_string());
57            env::set_var("MANGOFETCH_DATA_DIR", temp_dir.to_str().unwrap());
58
59            init_logging_ext(true, true);
60
61            let log_dir = temp_dir.join("logs");
62            assert!(log_dir.exists());
63
64            std::process::exit(0);
65        }
66
67        let exe = env::current_exe().unwrap();
68        let output = Command::new(exe)
69            .env("TEST_INIT_LOGGING_EXT", "1")
70            .arg("core::logger::tests::test_init_logging_ext_subprocess")
71            .arg("--exact")
72            .output()
73            .unwrap();
74
75        assert!(
76            output.status.success(),
77            "init_logging_ext failed: {:?}",
78            output
79        );
80    }
81
82    #[test]
83    fn test_init_logging_ext_no_stdout_subprocess() {
84        if env::var("TEST_INIT_LOGGING_EXT_NO_STDOUT").is_ok() {
85            let temp_dir = env::temp_dir().join(Uuid::new_v4().to_string());
86            env::set_var("MANGOFETCH_DATA_DIR", temp_dir.to_str().unwrap());
87
88            init_logging_ext(false, false);
89
90            let log_dir = temp_dir.join("logs");
91            assert!(log_dir.exists());
92
93            std::process::exit(0);
94        }
95
96        let exe = env::current_exe().unwrap();
97        let output = Command::new(exe)
98            .env("TEST_INIT_LOGGING_EXT_NO_STDOUT", "1")
99            .arg("core::logger::tests::test_init_logging_ext_no_stdout_subprocess")
100            .arg("--exact")
101            .output()
102            .unwrap();
103
104        assert!(
105            output.status.success(),
106            "init_logging_ext failed: {:?}",
107            output
108        );
109    }
110
111    #[test]
112    fn test_init_logging() {
113        if env::var("TEST_INIT_LOGGING").is_ok() {
114            let temp_dir = env::temp_dir().join(Uuid::new_v4().to_string());
115            env::set_var("MANGOFETCH_DATA_DIR", temp_dir.to_str().unwrap());
116
117            init_logging(false);
118
119            let log_dir = temp_dir.join("logs");
120            assert!(log_dir.exists());
121
122            std::process::exit(0);
123        }
124
125        let exe = env::current_exe().unwrap();
126        let output = Command::new(exe)
127            .env("TEST_INIT_LOGGING", "1")
128            .arg("core::logger::tests::test_init_logging")
129            .arg("--exact")
130            .output()
131            .unwrap();
132
133        assert!(output.status.success(), "init_logging failed: {:?}", output);
134    }
135}