//! An HTTP endpoint for dynamically setting tracing filters. 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>, path: PathBuf, } pub fn layer(path_root: &Path) -> (impl Layer, 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(); info!("writing flamegraph to disk..."); inferno::flamegraph::from_reader(&mut opts, reader, writer)?; Ok(()) } }