scuffle_pprof/
cpu.rs

1use std::io::Write;
2
3use flate2::Compression;
4use flate2::write::GzEncoder;
5use pprof::protos::Message;
6
7use crate::PprofError;
8
9/// A CPU profiler.
10///
11/// Call [`Cpu::capture`] to capture a pprof profile for the given duration.
12pub struct Cpu(pprof::ProfilerGuardBuilder);
13
14impl Cpu {
15    /// Create a new CPU profiler.
16    ///
17    /// - `frequency` is the sampling frequency in Hz.
18    /// - `blocklist` is a list of functions to exclude from the profile.
19    pub fn new<S: AsRef<str>>(frequency: i32, blocklist: &[S]) -> Self {
20        Self(
21            pprof::ProfilerGuardBuilder::default()
22                .frequency(frequency)
23                .blocklist(blocklist),
24        )
25    }
26
27    /// Capture a pprof profile for the given duration.
28    ///
29    /// The profile is compressed using gzip.
30    /// The profile can be analyzed using the `pprof` tool.
31    ///
32    /// <div class="warning">
33    /// Warning: This method is blocking and may take a long time to complete.
34    ///
35    /// It is recommended to run it in a separate thread.
36    /// </div>
37    pub fn capture(&self, duration: std::time::Duration) -> Result<Vec<u8>, PprofError> {
38        let profiler = self.0.clone().build()?;
39
40        std::thread::sleep(duration);
41
42        let report = profiler.report().build()?;
43
44        let pprof = report.pprof()?;
45
46        let mut gz = GzEncoder::new(Vec::new(), Compression::default());
47        gz.write_all(&pprof.encode_to_vec())?;
48        Ok(gz.finish()?)
49    }
50}