Skip to main content

wiki_tui/
logging.rs

1use anyhow::{Context, Result};
2use std::sync::Mutex;
3use tracing::level_filters::LevelFilter;
4use tracing_log::AsLog;
5use tracing_subscriber::{self, prelude::*, EnvFilter};
6
7use crate::config::{self, load_logging_config};
8
9const LOG_ENV: &str = "WIKI_TUI_LOG";
10
11pub fn initialize_logging(level: Option<LevelFilter>) -> Result<()> {
12    let logging_config = match load_logging_config() {
13        Ok(config) => config,
14        Err(error) => {
15            eprintln!("{:?}", error.context("failed loading the logging config"));
16            Default::default()
17        }
18    };
19
20    if !logging_config.enabled {
21        return Ok(());
22    }
23
24    let directory = config::cache_dir()?;
25    std::fs::create_dir_all(directory.clone())
26        .context(format!("{directory:?} could not be created"))?;
27    let log_path = directory.join("wiki-tui.log");
28    let log_file = std::fs::File::create(log_path)?;
29    let log_writer = Mutex::new(log_file);
30
31    let env_filter = EnvFilter::builder()
32        .with_default_directive(logging_config.level.into())
33        .with_env_var(LOG_ENV)
34        .from_env()?;
35    let level = match level {
36        Some(level) => level,
37        None => env_filter.max_level_hint().unwrap_or(logging_config.level),
38    };
39
40    let file_subscriber = tracing_subscriber::fmt::layer()
41        .with_file(true)
42        .with_line_number(true)
43        .with_writer(log_writer)
44        .with_target(false)
45        .with_ansi(false)
46        .with_filter(env_filter);
47
48    tracing_subscriber::registry()
49        .with(file_subscriber)
50        .with(tui_logger::TuiTracingSubscriberLayer)
51        .init();
52
53    tui_logger::set_default_level(level.as_log());
54
55    Ok(())
56}
57
58/// Similar to the `std::dbg!` macro, but generates `tracing` events rather
59/// than printing to stdout.
60///
61/// By default, the verbosity level for the generated events is `DEBUG`, but
62/// this can be customized.
63#[macro_export]
64macro_rules! trace_dbg {
65    (target: $target:expr, level: $level:expr, $ex:expr) => {{
66        match $ex {
67            value => {
68                tracing::event!(target: $target, $level, ?value, stringify!($ex));
69                value
70            }
71        }
72    }};
73    (level: $level:expr, $ex:expr) => {
74        $crate::trace_dbg!(target: module_path!(), level: $level, $ex)
75    };
76    (target: $target:expr, $ex:expr) => {
77        $crate::trace_dbg!(target: $target, level: tracing::Level::DEBUG, $ex)
78    };
79    ($ex:expr) => {
80        $crate::trace_dbg!(level: tracing::Level::DEBUG, $ex)
81    };
82}