summaryrefslogtreecommitdiffstats
path: root/src/log.rs
blob: 67974427f03b3fb875adca753820e04f79293a7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::sync::RwLock;

use anyhow::Result;
use lazy_static::lazy_static;
use log4rs;

use crate::constant_strings_paths::{ACTION_LOG_PATH, LOG_CONFIG_PATH};
use crate::utils::extract_lines;

// static ENV_HOME: &str = "$ENV{HOME}";

/// Set the logs.
/// The configuration is read from a config file defined in `LOG_CONFIG_PATH`
/// It's a YAML file which defines 2 logs:
/// - a normal one used directly with the macros like `log::info!(...)`, used for debugging
/// - a special one used with `log::info!(target: "special", ...)` to be displayed in the application
pub fn set_loggers() -> Result<()> {
    log4rs::init_file(
        shellexpand::tilde(LOG_CONFIG_PATH).as_ref(),
        Default::default(),
    )?;
    // clear_useless_env_home()?;

    log::info!("fm is starting");
    Ok(())
}

/// Delete useless $ENV{HOME} folder created by log4rs.
/// This folder is created when a log file is big enough to proc a rolling
/// Since the pattern can't be resolved, it's not created in the config folder but where the app is started...
/// See [github issue](https://github.com/estk/log4rs/issues/314)
/// The function log its results and delete nothing.
// fn clear_useless_env_home() -> Result<()> {
//     let p = std::path::Path::new(&ENV_HOME);
//     let cwd = std::env::current_dir();
//     log::info!(
//         "looking from {ENV_HOME} - {p}  CWD {cwd}",
//         p = p.display(),
//         cwd = cwd?.display()
//     );
//     if p.exists() && std::fs::metadata(ENV_HOME)?.is_dir()
//     // && std::path::Path::new(ENV_HOME).read_dir()?.next().is_none()
//     {
//         let z = std::path::Path::new(ENV_HOME).read_dir()?.next();
//         log::info!("z {z:?}");
//
//         // std::fs::remove_dir_all(ENV_HOME)?;
//         log::info!("Removed {ENV_HOME} empty directory from CWD");
//     }
//     Ok(())
// }

/// Returns the last line of the log file.
pub fn read_log() -> Result<Vec<String>> {
    let log_path = shellexpand::tilde(ACTION_LOG_PATH).to_string();
    let content = std::fs::read_to_string(log_path)?;
    Ok(extract_lines(content))
}

lazy_static! {
    static ref LAST_LOG_LINE: RwLock<String> = RwLock::new("".to_owned());
}

/// Read the last value of the "log line".
/// It's a global string created with `lazy_static!(...)`
/// Fail silently if the global variable can't be read and returns an empty string.
pub fn read_last_log_line() -> String {
    let Ok(last_log_line) = LAST_LOG_LINE.read() else {
        return "".to_owned();
    };
    last_log_line.to_owned()
}

/// Write a new log line to the global variable `LAST_LOG_LINE`.
/// It uses `lazy_static` to manipulate the global variable.
/// Fail silently if the global variable can't be written.
fn write_last_log_line<S>(log: S)
where
    S: Into<String> + std::fmt::Display,
{
    let Ok(mut new_log_line) = LAST_LOG_LINE.write() else {
        return;
    };
    *new_log_line = log.to_string();
}

/// Write a line to both the global variable `LAST_LOG_LINE` and the special log
/// which can be displayed with Alt+l
pub fn write_log_line<S>(log_line: S)
where
    S: Into<String> + std::fmt::Display,
{
    log::info!(target: "special", "{log_line}");
    write_last_log_line(log_line);
}

#[macro_export]
macro_rules! log_line {
    ($($arg:tt)+) => (
    $crate::log::write_log_line(
      format!($($arg)+)
    )
  );
}