返回 DeepSeek-TUI-2026
audit.rs
根目录 / crates / tui / src / audit.rs
1 //! Lightweight audit logging for sensitive operations.
2
3 use std::fs;
4 use std::path::PathBuf;
5
6 use chrono::Utc;
7 use serde_json::{Value, json};
8
9 use crate::utils::{flush_and_sync, open_append};
10
11 /// Append an audit event to `~/.deepseek/audit.log`.
12 ///
13 /// This helper is best-effort by design: callers should not fail critical flows
14 /// if audit persistence fails.
15 pub fn log_sensitive_event(event: &str, details: Value) {
16 if let Err(err) = append_event(event, details) {
17 crate::logging::warn(format!("audit log write failed: {err}"));
18 }
19 }
20
21 fn append_event(event: &str, details: Value) -> anyhow::Result<()> {
22 let path = default_audit_path()?;
23 let parent = path.parent().map(|p| p.to_path_buf());
24 if let Some(ref parent) = parent {
25 fs::create_dir_all(parent)?;
26 }
27 // Open for append with a BufWriter for buffered I/O, then flush + fsync
28 // after each event so the record is durably on disk.
29 let mut writer = open_append(&path)?;
30 let record = json!({
31 "ts": Utc::now().to_rfc3339(),
32 "event": event,
33 "details": details,
34 });
35 let line = serde_json::to_string(&record)?;
36 use std::io::Write;
37 writeln!(writer, "{line}")?;
38 flush_and_sync(&mut writer)?;
39 Ok(())
40 }
41
42 fn default_audit_path() -> anyhow::Result<PathBuf> {
43 let home = dirs::home_dir().ok_or_else(|| anyhow::anyhow!("home directory not found"))?;
44 Ok(home.join(".deepseek").join("audit.log"))
45 }
46
46 lines RUST