1use std::fs::File;
7use std::io::Write;
8use std::path::Path;
9
10use crate::error::{Error, Result};
11use pprof::protos::Message;
12
13pub struct CpuProfiler {
15 guard: pprof::ProfilerGuard<'static>,
16}
17
18impl CpuProfiler {
19 pub fn start() -> Result<Self> {
25 let guard = pprof::ProfilerGuard::new(100)
26 .map_err(|e| Error::runtime_with_source("failed to start CPU profiler", e))?;
27 Ok(Self { guard })
28 }
29
30 pub fn stop_to_file<P: AsRef<Path>>(self, path: P) -> Result<()> {
37 let report = self
38 .guard
39 .report()
40 .build()
41 .map_err(|e| Error::runtime_with_source("failed to build CPU profile report", e))?;
42 let profile = report.pprof().map_err(|e| {
43 Error::runtime_with_source("failed to encode CPU profile to protobuf", e)
44 })?;
45 let mut f = File::create(path.as_ref()).map_err(|e| {
46 Error::io_with_source(
47 format!("failed to create profile file: {}", path.as_ref().display()),
48 e,
49 )
50 })?;
51 let buf = profile.encode_to_vec();
53 f.write_all(&buf)
54 .map_err(|e| Error::io_with_source("failed to write CPU profile", e))?;
55 Ok(())
56 }
57}
58
59#[cfg(feature = "heap-profiling")]
61pub mod heap {
62 use crate::error::Result;
63 use std::path::Path;
64
65 pub struct HeapProfiler {
67 _prof: dhat::Profiler,
68 }
69
70 impl HeapProfiler {
71 pub fn start<P: AsRef<Path>>(output: Option<P>) -> Result<Self> {
77 if let Some(p) = output {
78 std::env::set_var("DHAT_OUT", p.as_ref());
79 }
80 let profiler = dhat::Profiler::new_heap();
81 Ok(Self { _prof: profiler })
82 }
83
84 pub fn stop(self) {
86 }
88 }
89}
90
91#[cfg(not(feature = "heap-profiling"))]
93pub mod heap {
94 use crate::error::{Error, ErrorCode, Result};
95 use std::path::Path;
96
97 pub fn start<P: AsRef<Path>>(_output: Option<P>) -> Result<()> {
99 Err(Error::platform_with_code(
100 ErrorCode::PlatformFeatureNotAvailable,
101 "heap profiling is not available in this build",
102 std::env::consts::OS,
103 ))
104 }
105}