1use std::path::PathBuf;
2
3use color_eyre::eyre::Result;
4use lazy_static::lazy_static;
5use tracing::info;
6use tracing_error::ErrorLayer;
7use tracing_subscriber::{self, layer::SubscriberExt, util::SubscriberInitExt};
8
9use crate::config::get_app_config_path;
10
11lazy_static! {
14 pub static ref PROJECT_NAME: String = env!("CARGO_CRATE_NAME").to_uppercase().to_string();
15 pub static ref LOG_ENV: String = format!("{}_LOGLEVEL", PROJECT_NAME.clone());
16 pub static ref LOG_FILE: String = format!("{}.log", env!("CARGO_PKG_NAME"));
17}
18
19fn project_directory() -> Option<PathBuf> {
20 dirs_next::data_dir().map(|data_dir| data_dir.join(env!("CARGO_CRATE_NAME")))
21}
22
23pub fn get_log_dir() -> PathBuf {
24 if let Some(p) = project_directory() {
25 p
26 } else if let Ok(p) = get_app_config_path() {
27 p
28 } else {
29 PathBuf::from(".").join(".data")
30 }
31}
32
33pub fn initialize_logging(log_to: &Option<PathBuf>) -> Result<()> {
34 let log_path = match log_to {
35 Some(p) => p.clone(),
36 None => {
37 let directory = get_log_dir();
38 std::fs::create_dir_all(directory.clone())?;
39 directory.join(LOG_FILE.clone())
40 }
41 };
42
43 let log_file = std::fs::File::create(log_path)?;
44 std::env::set_var(
45 "RUST_LOG",
46 std::env::var("RUST_LOG")
47 .or_else(|_| std::env::var(LOG_ENV.clone()))
48 .unwrap_or_else(|_| format!("{}=info", env!("CARGO_CRATE_NAME"))),
49 );
50 let file_subscriber = tracing_subscriber::fmt::layer()
51 .with_file(true)
52 .with_line_number(true)
53 .with_writer(log_file)
54 .with_target(false)
55 .with_ansi(false);
56 tracing_subscriber::registry()
57 .with(file_subscriber)
58 .with(ErrorLayer::default())
59 .with(tracing_subscriber::filter::EnvFilter::from_default_env())
60 .init();
61
62 info!("logging initialised");
63 Ok(())
64}
65
66#[macro_export]
72macro_rules! trace_dbg {
73 (target: $target:expr, level: $level:expr, $ex:expr) => {{
74 match $ex {
75 value => {
76 tracing::event!(target: $target, $level, ?value, stringify!($ex));
77 value
78 }
79 }
80 }};
81 (level: $level:expr, $ex:expr) => {
82 trace_dbg!(target: module_path!(), level: $level, $ex)
83 };
84 (target: $target:expr, $ex:expr) => {
85 trace_dbg!(target: $target, level: tracing::Level::DEBUG, $ex)
86 };
87 ($ex:expr) => {
88 trace_dbg!(level: tracing::Level::DEBUG, $ex)
89 };
90}