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}