par_term/tab/
session_logging.rs1use crate::config::{Config, SessionLogFormat};
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
67 if config.session_log.session_log_format == SessionLogFormat::AsciicastV3 {
70 let tm = Arc::clone(&self.terminal);
71 logger.set_v3_exporter(Box::new(move |session| {
72 tm.try_read()
73 .ok()
74 .map(|tm| tm.export_session_asciicast_v3(session))
75 }));
76 }
77
78 logger.start()?;
79
80 eprintln!(
84 "\n[par-term SESSION LOGGING ENABLED]\n\
85 Session output is now being recorded to: {}\n\
86 WARNING: Session logs may capture sensitive data (passwords, API keys, tokens)\n\
87 despite heuristic redaction. Password-prompt detection is enabled: {}\n\
88 Do NOT share session log files unless you have reviewed their contents.\n\
89 Disable session logging when working with sensitive credentials.\n",
90 logs_dir.display(),
91 config.session_log.session_log_redact_passwords,
92 );
93
94 let logger_clone = Arc::clone(&self.session_logger);
96 if let Ok(term) = self.terminal.try_read() {
97 term.set_output_callback(move |data: &[u8]| {
98 if let Some(ref mut logger) = *logger_clone.lock() {
99 logger.record_output(data);
100 }
101 });
102 }
103
104 *logger_guard = Some(logger);
105 log::info!("Session logging created and started via hotkey");
106 Ok(true)
107 }
108 }
109
110 pub fn is_session_logging_active(&self) -> bool {
112 if let Some(ref logger) = *self.session_logger.lock() {
113 logger.is_active()
114 } else {
115 false
116 }
117 }
118}