1use colored::{ColoredString, Colorize};
2use std::env;
3use std::sync::LazyLock;
4
5static GHOSTSYNC_LOG_LEVEL: LazyLock<Level> = LazyLock::new(Level::from_env);
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
8pub enum Level {
9 Trace = 0,
10 Debug = 1,
11 Info = 2,
12 Warn = 3,
13 Error = 4,
14}
15
16impl Level {
17 fn from_env() -> Self {
18 dotenv::dotenv().ok();
19
20 env::var("LOG_LEVEL")
21 .ok()
22 .and_then(|s| match s.to_lowercase().as_str() {
23 "trace" => Some(Level::Trace),
24 "debug" => Some(Level::Debug),
25 "info" => Some(Level::Info),
26 "warn" => Some(Level::Warn),
27 "error" => Some(Level::Error),
28 _ => None,
29 })
30 .unwrap_or(Level::Info)
31 }
32}
33
34#[inline]
35fn should_log(level: Level) -> bool {
36 level >= *GHOSTSYNC_LOG_LEVEL
37}
38
39#[inline]
40pub fn log(level: Level, msg: ColoredString) {
41 if !should_log(level) {
42 return;
43 }
44
45 let now = chrono::Local::now();
46
47 let level_str = match level {
48 Level::Trace => "TRACE".dimmed(),
49 Level::Debug => "DEBUG".blue().bold(),
50 Level::Info => "INFO".green().bold(),
51 Level::Warn => "WARN".yellow().bold(),
52 Level::Error => "ERROR".red().bold(),
53 };
54
55 println!("[{}][{}] {}", now.format("%H:%M:%S"), level_str, msg);
56}
57
58#[macro_export]
59macro_rules! trace {
60 ($($arg:tt)*) => {
61 {
62 use colored::Colorize;
63 $crate::log::log($crate::log::Level::Trace, format!($($arg)*).dimmed())
64 }
65 };
66}
67
68#[macro_export]
69macro_rules! debug {
70 ($($arg:tt)*) => {
71 {
72 use colored::Colorize;
73 $crate::log::log($crate::log::Level::Debug, format!($($arg)*).blue())
74 }
75 };
76}
77
78#[macro_export]
79macro_rules! info {
80 ($($arg:tt)*) => {
81 {
82 use colored::Colorize;
83 $crate::log::log($crate::log::Level::Info, format!($($arg)*).green())
84 }
85 };
86}
87
88#[macro_export]
89macro_rules! warn {
90 ($($arg:tt)*) => {
91 {
92 use colored::Colorize;
93 $crate::log::log($crate::log::Level::Warn, format!($($arg)*).yellow())
94 }
95 };
96}
97
98#[macro_export]
99macro_rules! error {
100 ($($arg:tt)*) => {
101 {
102 use colored::Colorize;
103 $crate::log::log($crate::log::Level::Error, format!($($arg)*).red())
104 }
105 };
106}