zebrad/components/tracing/
flame.rs
1use color_eyre::eyre::Report;
4use std::{
5 fs::File,
6 io::{BufReader, BufWriter},
7 path::Path,
8 path::PathBuf,
9};
10use tracing::Subscriber;
11use tracing_subscriber::{registry::LookupSpan, Layer};
12
13pub struct Grapher {
14 guard: tracing_flame::FlushGuard<BufWriter<File>>,
15 path: PathBuf,
16}
17
18pub fn layer<S>(path_root: &Path) -> (impl Layer<S>, Grapher)
19where
20 S: Subscriber + for<'span> LookupSpan<'span>,
21{
22 let path = path_root.with_extension("folded");
23 let (layer, guard) = tracing_flame::FlameLayer::with_file(&path).unwrap();
24 let layer = layer.with_empty_samples(false).with_threads_collapsed(true);
25 let flamegrapher = Grapher { guard, path };
26 (layer, flamegrapher)
27}
28
29impl Grapher {
30 pub fn write_flamegraph(&self) -> Result<(), Report> {
31 self.guard.flush()?;
32 let out_path = self.path.with_extension("svg");
33 let inf = File::open(&self.path)?;
34 let reader = BufReader::new(inf);
35
36 let out = File::create(out_path)?;
37 let writer = BufWriter::new(out);
38
39 let mut opts = inferno::flamegraph::Options::default();
40 debug!("writing flamegraph to disk...");
41 inferno::flamegraph::from_reader(&mut opts, reader, writer)?;
42
43 Ok(())
44 }
45}