Files
scpcap/src/tracelog.rs
T
eric bc2ee2d374 Truncate --log file on open instead of appending
Each scpcap invocation now starts its log fresh. Appending meant a re-run
after a failed attempt mixed new output in with (or could be mistaken for)
stale output from the previous run -- confusing when diagnosing exactly
this kind of issue in production.
2026-08-28 09:47:27 -04:00

34 lines
1.2 KiB
Rust

use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::Path;
use std::sync::Mutex;
use std::time::{SystemTime, UNIX_EPOCH};
/// Optional diagnostic trace, one timestamped line per event, for diagnosing
/// where a transfer stalls (e.g. which side is still waiting, and on what).
/// `Logger::none()` is a no-op so call sites don't need to branch on whether
/// `--log` was given.
pub struct Logger(Option<Mutex<File>>);
impl Logger {
pub fn none() -> Logger {
Logger(None)
}
/// Truncates any existing file at `path` -- each run starts a fresh
/// log, so a re-run never leaves stale lines from a previous attempt
/// mixed in with (or mistaken for) the current one.
pub fn open(path: &Path) -> std::io::Result<Logger> {
let f = OpenOptions::new().create(true).write(true).truncate(true).open(path)?;
Ok(Logger(Some(Mutex::new(f))))
}
pub fn log(&self, args: std::fmt::Arguments) {
let Some(m) = &self.0 else { return };
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default();
if let Ok(mut f) = m.lock() {
let _ = writeln!(f, "[{:.6}] {}", now.as_secs_f64(), args);
}
}
}