use color_eyre::eyre::Report;
use std::{
fs::File,
io::{BufReader, BufWriter},
path::Path,
path::PathBuf,
};
use tracing::Subscriber;
use tracing_subscriber::{registry::LookupSpan, Layer};
pub struct Grapher {
guard: tracing_flame::FlushGuard<BufWriter<File>>,
path: PathBuf,
}
pub fn layer<S>(path_root: &Path) -> (impl Layer<S>, Grapher)
where
S: Subscriber + for<'span> LookupSpan<'span>,
{
let path = path_root.with_extension("folded");
let (layer, guard) = tracing_flame::FlameLayer::with_file(&path).unwrap();
let layer = layer.with_empty_samples(false).with_threads_collapsed(true);
let flamegrapher = Grapher { guard, path };
(layer, flamegrapher)
}
impl Grapher {
pub fn write_flamegraph(&self) -> Result<(), Report> {
self.guard.flush()?;
let out_path = self.path.with_extension("svg");
let inf = File::open(&self.path)?;
let reader = BufReader::new(inf);
let out = File::create(out_path)?;
let writer = BufWriter::new(out);
let mut opts = inferno::flamegraph::Options::default();
debug!("writing flamegraph to disk...");
inferno::flamegraph::from_reader(&mut opts, reader, writer)?;
Ok(())
}
}