Skip to main content

mcp_gmailcal/
logging.rs

1use chrono::Local;
2use log::LevelFilter;
3use simplelog::{self, CombinedLogger, TermLogger, WriteLogger};
4use std::fs::OpenOptions;
5use std::io::Write;
6
7/// Sets up logging to file and stderr
8///
9/// # Arguments
10///
11/// * `log_level` - The level of log messages to capture
12/// * `log_file` - Optional path to log file. If None, creates a timestamped file
13///
14/// # Returns
15///
16/// Sets up the logging system
17///
18/// # Arguments
19///
20/// * `log_level` - The level of logging to use
21/// * `log_file` - Optional log file name or "memory" to use in-memory logging
22///
23/// # Returns
24///
25/// The path to the log file or a description of the logging destination
26pub fn setup_logging(log_level: LevelFilter, log_file: Option<&str>) -> std::io::Result<String> {
27    // Use the default config for simplicity - explicitly use simplelog::Config to avoid ambiguity
28    let log_config = simplelog::Config::default();
29
30    // Check if we should use memory-only logging
31    if log_file == Some("memory") {
32        // For memory-only logging, just use stderr
33        TermLogger::init(
34            log_level,
35            log_config,
36            simplelog::TerminalMode::Stderr,
37            simplelog::ColorChoice::Auto,
38        )
39        .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
40
41        log::info!("Logging initialized to stderr only (memory mode)");
42        log::debug!("Debug logging enabled");
43
44        return Ok(String::from("stderr-only (memory mode)"));
45    }
46
47    // Create a timestamp for the log file
48    let timestamp = Local::now().format("%Y%m%d_%H").to_string();
49
50    // Determine log file path
51    let log_path = match log_file {
52        Some(path) => path.to_string(),
53        None => format!("gmail_mcp_{}.log", timestamp),
54    };
55
56    // Create the log file with append mode and write header in one operation
57    let mut log_file = OpenOptions::new()
58        .create(true)
59        .append(true)
60        .open(&log_path)?;
61
62    writeln!(
63        log_file,
64        "====== GMAIL MCP SERVER LOG - Started at {} ======",
65        Local::now().format("%Y-%m-%d %H:%M:%S")
66    )?;
67
68    // Setup loggers to write to both file and stderr
69    CombinedLogger::init(vec![
70        // File logger
71        WriteLogger::new(log_level, log_config.clone(), log_file),
72        // Terminal logger for stderr
73        TermLogger::new(
74            log_level,
75            log_config,
76            simplelog::TerminalMode::Stderr,
77            simplelog::ColorChoice::Auto,
78        ),
79    ])
80    .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
81
82    log::info!("Logging initialized to file: {} and stderr", log_path);
83    log::debug!("Debug logging enabled");
84
85    Ok(log_path)
86}