Skip to main content

j_cli/util/
log.rs

1use crate::constants::{AGENT_DIR, AGENT_LOG_DIR, DATA_DIR};
2use chrono::Local;
3use std::fs::{self, OpenOptions};
4use std::io::Write;
5use std::path::PathBuf;
6
7/// 打印普通信息
8#[macro_export]
9macro_rules! info {
10    ($($arg:tt)*) => {{
11        println!($($arg)*)
12    }};
13}
14
15/// 打印错误信息
16#[macro_export]
17macro_rules! error {
18    ($($arg:tt)*) => {{
19        use colored::Colorize;
20        eprint!("{}", "[ERROR] ".red());
21        eprintln!($($arg)*)
22    }};
23}
24
25/// 打印 usage 提示
26#[macro_export]
27macro_rules! usage {
28    ($($arg:tt)*) => {{
29        use colored::Colorize;
30        print!("{}", "💡 Usage: ".green());
31        println!($($arg)*)
32    }};
33}
34
35/// 打印 debug 日志(仅 verbose 模式下输出)
36#[macro_export]
37macro_rules! debug_log {
38    ($config:expr, $($arg:tt)*) => {{
39        if $config.is_verbose() {
40            println!($($arg)*)
41        }
42    }};
43}
44
45/// 打印分隔线
46#[allow(dead_code)]
47pub fn print_line() {
48    println!("- - - - - - - - - - - - - - - - - - - - - - -");
49}
50
51/// 首字母大写
52pub fn capitalize_first_letter(s: &str) -> String {
53    let mut chars = s.chars();
54    match chars.next() {
55        None => String::new(),
56        Some(c) => c.to_uppercase().collect::<String>() + chars.as_str(),
57    }
58}
59
60/// 写入信息日志到文件
61/// 日志文件位置:~/.jdata/agent/logs/info.log
62pub fn write_info_log(context: &str, content: &str) {
63    let log_dir = dirs::home_dir()
64        .unwrap_or_else(|| PathBuf::from("."))
65        .join(DATA_DIR)
66        .join(AGENT_DIR)
67        .join(AGENT_LOG_DIR);
68
69    if let Err(e) = fs::create_dir_all(&log_dir) {
70        eprintln!("无法创建日志目录: {}", e);
71        return;
72    }
73
74    let log_file = log_dir.join("info.log");
75
76    match OpenOptions::new().create(true).append(true).open(&log_file) {
77        Ok(mut file) => {
78            let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S");
79            let log_entry = format!(
80                "\n========================================\n[{}] {}\n{}\n",
81                timestamp, context, content
82            );
83            if let Err(e) = file.write_all(log_entry.as_bytes()) {
84                eprintln!("写入信息日志失败: {}", e);
85            }
86        }
87        Err(e) => {
88            eprintln!("无法打开信息日志文件: {}", e);
89        }
90    }
91}
92
93/// 写入错误日志到文件
94/// 日志文件位置:~/.jdata/agent/logs/error.log
95pub fn write_error_log(context: &str, error: &str) {
96    let log_dir = dirs::home_dir()
97        .unwrap_or_else(|| PathBuf::from("."))
98        .join(DATA_DIR)
99        .join(AGENT_DIR)
100        .join(AGENT_LOG_DIR);
101
102    // 创建日志目录
103    if let Err(e) = fs::create_dir_all(&log_dir) {
104        eprintln!("无法创建日志目录: {}", e);
105        return;
106    }
107
108    let log_file = log_dir.join("error.log");
109
110    // 写入日志
111    match OpenOptions::new().create(true).append(true).open(&log_file) {
112        Ok(mut file) => {
113            let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S");
114            let log_entry = format!(
115                "\n========================================\n[{}] {}\n错误详情:\n{}\n",
116                timestamp, context, error
117            );
118            if let Err(e) = file.write_all(log_entry.as_bytes()) {
119                eprintln!("写入错误日志失败: {}", e);
120            }
121        }
122        Err(e) => {
123            eprintln!("无法打开错误日志文件: {}", e);
124        }
125    }
126}