use std::fs::OpenOptions;
use std::io::{BufWriter, Write};
use std::sync::Mutex;
use std::sync::OnceLock;
use std::time::Instant;
struct TraceState {
started: Instant,
writer: Mutex<BufWriter<std::fs::File>>,
}
static STATE: OnceLock<Option<TraceState>> = OnceLock::new();
fn state() -> &'static Option<TraceState> {
STATE.get_or_init(|| {
let path = std::env::var("RDOM_TRACE").ok()?;
if path.is_empty() {
return None;
}
let file = OpenOptions::new()
.create(true)
.append(true)
.open(&path)
.ok()?;
let mut writer = BufWriter::new(file);
let _ = writeln!(
writer,
"\n========== process start (pid={}) ==========",
std::process::id()
);
let _ = writer.flush();
Some(TraceState {
started: Instant::now(),
writer: Mutex::new(writer),
})
})
}
#[inline]
pub fn enabled() -> bool {
state().is_some()
}
pub fn write_line(line: &str) {
let Some(s) = state().as_ref() else {
return;
};
let ms = s.started.elapsed().as_millis();
let Ok(mut w) = s.writer.lock() else { return };
let _ = writeln!(w, "[{ms:>8}ms] {line}");
let _ = w.flush();
}
#[macro_export]
macro_rules! rdom_trace {
($($arg:tt)*) => {
if $crate::runtime::trace::enabled() {
$crate::runtime::trace::write_line(&format!($($arg)*));
}
};
}