Skip to main content

mermaid_cli/utils/
logger.rs

1use std::fs::OpenOptions;
2use std::path::PathBuf;
3use tracing::{debug, error, info, warn};
4use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
5
6/// Get the log file path (~/.mermaid/mermaid.log)
7fn get_log_file_path() -> Option<PathBuf> {
8    std::env::var("HOME")
9        .ok()
10        .map(|home| PathBuf::from(home).join(".mermaid").join("mermaid.log"))
11}
12
13/// Initialize the logging system with tracing
14pub fn init_logger(verbose: bool) {
15    // If --verbose flag is set, override to debug level
16    // Otherwise use RUST_LOG environment variable, default to warn level (quieter)
17    let filter = if verbose {
18        EnvFilter::new("debug,mermaid=debug")
19    } else {
20        EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("warn,mermaid=info"))
21    };
22
23    // Try to write logs to a file to avoid corrupting the TUI
24    // Falls back to no logging if file creation fails (TUI takes priority)
25    if let Some(log_path) = get_log_file_path() {
26        // Ensure parent directory exists
27        if let Some(parent) = log_path.parent() {
28            let _ = std::fs::create_dir_all(parent);
29        }
30
31        // Open log file for appending
32        if let Ok(file) = OpenOptions::new()
33            .create(true)
34            .append(true)
35            .open(&log_path)
36        {
37            let fmt_layer = tracing_subscriber::fmt::layer()
38                .with_writer(file)
39                .with_target(false)
40                .with_thread_ids(false)
41                .with_thread_names(false)
42                .with_ansi(false) // No ANSI colors in file
43                .compact();
44
45            tracing_subscriber::registry()
46                .with(filter)
47                .with(fmt_layer)
48                .init();
49            return;
50        }
51    }
52
53    // Fallback: no logging if file creation fails (don't corrupt TUI)
54    tracing_subscriber::registry()
55        .with(filter)
56        .init();
57}
58
59/// Log an info message with category prefix (backward compatible)
60pub fn log_info(category: &str, message: impl std::fmt::Display) {
61    info!(category = %category, "{}", message);
62}
63
64/// Log a warning message with category prefix (backward compatible)
65pub fn log_warn(category: &str, message: impl std::fmt::Display) {
66    warn!(category = %category, "{}", message);
67}
68
69/// Log an error message with category prefix (backward compatible)
70pub fn log_error(category: &str, message: impl std::fmt::Display) {
71    error!(category = %category, "{}", message);
72}
73
74/// Log a debug message (backward compatible)
75pub fn log_debug(message: impl std::fmt::Display) {
76    debug!("{}", message);
77}
78
79/// Progress indicator for startup sequence
80pub fn log_progress(step: usize, total: usize, message: impl std::fmt::Display) {
81    info!(step = step, total = total, "{}", message);
82}