use std::fs::File;
use std::io::Write;
use std::path::Path;
use crate::error::{Error, Result};
use pprof::protos::Message;
pub struct CpuProfiler {
guard: pprof::ProfilerGuard<'static>,
}
impl CpuProfiler {
pub fn start() -> Result<Self> {
let guard = pprof::ProfilerGuard::new(100)
.map_err(|e| Error::runtime_with_source("failed to start CPU profiler", e))?;
Ok(Self { guard })
}
pub fn stop_to_file<P: AsRef<Path>>(self, path: P) -> Result<()> {
let report = self
.guard
.report()
.build()
.map_err(|e| Error::runtime_with_source("failed to build CPU profile report", e))?;
let profile = report.pprof().map_err(|e| {
Error::runtime_with_source("failed to encode CPU profile to protobuf", e)
})?;
let mut f = File::create(path.as_ref()).map_err(|e| {
Error::io_with_source(
format!("failed to create profile file: {}", path.as_ref().display()),
e,
)
})?;
let buf = profile.encode_to_vec();
f.write_all(&buf)
.map_err(|e| Error::io_with_source("failed to write CPU profile", e))?;
Ok(())
}
}
#[cfg(feature = "heap-profiling")]
pub mod heap {
use crate::error::Result;
use std::path::Path;
pub struct HeapProfiler {
_prof: dhat::Profiler,
}
impl HeapProfiler {
pub fn start<P: AsRef<Path>>(output: Option<P>) -> Result<Self> {
if let Some(p) = output {
std::env::set_var("DHAT_OUT", p.as_ref());
}
let profiler = dhat::Profiler::new_heap();
Ok(Self { _prof: profiler })
}
pub fn stop(self) {
}
}
}
#[cfg(not(feature = "heap-profiling"))]
pub mod heap {
use crate::error::{Error, ErrorCode, Result};
use std::path::Path;
pub fn start<P: AsRef<Path>>(_output: Option<P>) -> Result<()> {
Err(Error::platform_with_code(
ErrorCode::PlatformFeatureNotAvailable,
"heap profiling is not available in this build",
std::env::consts::OS,
))
}
}