Skip to main content

csh/
log.rs

1//! Logging module for color-ssh
2//!
3//! Provides structured logging capabilities with different levels:
4//! - DEBUG: Detailed diagnostic information
5//! - INFO: General informational messages
6//! - WARN: Warning messages for potentially problematic situations
7//! - ERROR: Error messages for failures
8//!
9//! Also includes specialized SSH session logging.
10
11mod debug;
12mod errors;
13mod formatter;
14mod macros;
15mod ssh;
16
17pub use errors::LogError;
18
19use once_cell::sync::Lazy;
20use std::sync::atomic::{AtomicBool, Ordering};
21
22// Global flags for enabling different logging types
23static DEBUG_MODE: AtomicBool = AtomicBool::new(false);
24static SSH_LOGGING: AtomicBool = AtomicBool::new(false);
25
26// Global logger instance to avoid recreating loggers on every macro call
27pub static LOGGER: Lazy<Logger> = Lazy::new(Logger::new);
28
29#[derive(Debug, Clone, Copy)]
30pub enum LogLevel {
31    Debug,
32    Info,
33    Warning,
34    Error,
35}
36
37impl LogLevel {
38    fn as_str(&self) -> &'static str {
39        match self {
40            LogLevel::Debug => "DEBUG",
41            LogLevel::Info => "INFO",
42            LogLevel::Warning => "WARN",
43            LogLevel::Error => "ERROR",
44        }
45    }
46}
47
48#[derive(Clone, Default)]
49pub struct Logger {
50    debug_logger: debug::DebugLogger,
51    ssh_logger: ssh::SshLogger,
52}
53
54impl Logger {
55    pub fn new() -> Self {
56        Self::default()
57    }
58
59    pub fn enable_debug(&self) {
60        DEBUG_MODE.store(true, Ordering::SeqCst);
61    }
62
63    pub fn disable_debug(&self) {
64        DEBUG_MODE.store(false, Ordering::SeqCst);
65    }
66
67    pub fn enable_ssh_logging(&self) {
68        SSH_LOGGING.store(true, Ordering::SeqCst);
69    }
70
71    pub fn disable_ssh_logging(&self) {
72        SSH_LOGGING.store(false, Ordering::SeqCst);
73    }
74
75    pub fn is_debug_enabled(&self) -> bool {
76        DEBUG_MODE.load(Ordering::SeqCst)
77    }
78
79    pub fn is_ssh_logging_enabled(&self) -> bool {
80        SSH_LOGGING.load(Ordering::SeqCst)
81    }
82
83    /// Log a debug message (only when debug mode is enabled)
84    pub fn log_debug(&self, message: &str) -> Result<(), LogError> {
85        if self.is_debug_enabled() {
86            self.debug_logger.log(LogLevel::Debug, message)?;
87        }
88        Ok(())
89    }
90
91    /// Log an informational message (only when debug mode is enabled)
92    pub fn log_info(&self, message: &str) -> Result<(), LogError> {
93        if self.is_debug_enabled() {
94            self.debug_logger.log(LogLevel::Info, message)?;
95        }
96        Ok(())
97    }
98
99    /// Log a warning message (only when debug mode is enabled)
100    pub fn log_warn(&self, message: &str) -> Result<(), LogError> {
101        if self.is_debug_enabled() {
102            self.debug_logger.log(LogLevel::Warning, message)?;
103        }
104        Ok(())
105    }
106
107    /// Log an error message (only when debug mode is enabled)
108    pub fn log_error(&self, message: &str) -> Result<(), LogError> {
109        if self.is_debug_enabled() {
110            self.debug_logger.log(LogLevel::Error, message)?;
111        }
112        Ok(())
113    }
114
115    /// Log SSH session output
116    pub fn log_ssh(&self, message: &str) -> Result<(), LogError> {
117        if self.is_ssh_logging_enabled() {
118            self.ssh_logger.log(message)?;
119        }
120        Ok(())
121    }
122}