par_term/tab/
session_logging.rs1use crate::config::Config;
6use crate::session_logger::SessionLogger;
7use crate::tab::Tab;
8use std::sync::Arc;
9
10impl Tab {
11 pub fn toggle_session_logging(&mut self, config: &Config) -> anyhow::Result<bool> {
16 let mut logger_guard = self.session_logger.lock();
17
18 if let Some(ref mut logger) = *logger_guard {
19 if logger.is_active() {
21 logger.stop()?;
22 log::info!("Session logging stopped via hotkey");
23 Ok(false)
24 } else {
25 logger.start()?;
26 log::info!("Session logging started via hotkey");
27 Ok(true)
28 }
29 } else {
30 let logs_dir = config.logs_dir();
32 if let Err(e) = std::fs::create_dir_all(&logs_dir) {
33 log::warn!("Failed to create logs directory: {}", e);
34 return Err(anyhow::anyhow!("Failed to create logs directory: {}", e));
35 }
36 #[cfg(unix)]
40 {
41 use std::os::unix::fs::PermissionsExt;
42 let _ = std::fs::set_permissions(&logs_dir, std::fs::Permissions::from_mode(0o700));
43 }
44
45 let dimensions = if let Ok(term) = self.terminal.try_read() {
47 term.dimensions()
48 } else {
49 (80, 24) };
51
52 let session_title = Some(format!(
53 "{} - {}",
54 self.title,
55 chrono::Local::now().format("%Y-%m-%d %H:%M:%S")
56 ));
57
58 let mut logger = SessionLogger::new(
59 config.session_log.session_log_format,
60 &logs_dir,
61 dimensions,
62 session_title,
63 )?;
64
65 logger.set_redact_passwords(config.session_log.session_log_redact_passwords);
66 logger.start()?;
67
68 eprintln!(
72 "\n[par-term SESSION LOGGING ENABLED]\n\
73 Session output is now being recorded to: {}\n\
74 WARNING: Session logs may capture sensitive data (passwords, API keys, tokens)\n\
75 despite heuristic redaction. Password-prompt detection is enabled: {}\n\
76 Do NOT share session log files unless you have reviewed their contents.\n\
77 Disable session logging when working with sensitive credentials.\n",
78 logs_dir.display(),
79 config.session_log.session_log_redact_passwords,
80 );
81
82 let logger_clone = Arc::clone(&self.session_logger);
84 if let Ok(term) = self.terminal.try_read() {
85 term.set_output_callback(move |data: &[u8]| {
86 if let Some(ref mut logger) = *logger_clone.lock() {
87 logger.record_output(data);
88 }
89 });
90 }
91
92 *logger_guard = Some(logger);
93 log::info!("Session logging created and started via hotkey");
94 Ok(true)
95 }
96 }
97
98 pub fn is_session_logging_active(&self) -> bool {
100 if let Some(ref logger) = *self.session_logger.lock() {
101 logger.is_active()
102 } else {
103 false
104 }
105 }
106}