use std::sync::{Arc, Mutex, OnceLock};
use fastrace::collector::{Config, Reporter, SpanId, SpanRecord};
#[derive(Debug)]
pub(crate) struct RawSpan {
pub name: String,
pub duration_ns: u64,
pub span_id: SpanId,
pub parent_id: SpanId,
}
static SINK: OnceLock<Arc<Mutex<Vec<RawSpan>>>> = OnceLock::new();
fn sink() -> Arc<Mutex<Vec<RawSpan>>> {
SINK.get_or_init(|| {
let buf: Arc<Mutex<Vec<RawSpan>>> = Default::default();
fastrace::set_reporter(BenchReporter(Arc::clone(&buf)), Config::default());
buf
})
.clone()
}
struct BenchReporter(Arc<Mutex<Vec<RawSpan>>>);
impl Reporter for BenchReporter {
fn report(&mut self, spans: Vec<SpanRecord>) {
let mut buf = self.0.lock().unwrap();
for s in spans {
buf.push(RawSpan {
name: s.name.into_owned(),
duration_ns: s.duration_ns,
span_id: s.span_id,
parent_id: s.parent_id,
});
}
}
}
pub(crate) fn init() {
sink();
}
pub(crate) fn drain() -> Vec<RawSpan> {
fastrace::flush();
std::mem::take(&mut *sink().lock().unwrap())
}