Skip to content

Commit 796c209

Browse files
authored
feat: add cpu profiler (#817)
1 parent 8199c9d commit 796c209

File tree

3 files changed

+98
-8
lines changed

3 files changed

+98
-8
lines changed

Cargo.lock

+60-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ logger = { workspace = true }
3535
meta_client = { workspace = true }
3636
opensrv-mysql = "0.1.0"
3737
paste = { workspace = true }
38+
pprof = { version = "0.11.1", features = ["flamegraph"] }
3839
profile = { workspace = true }
3940
prom-remote-api = { version = "0.2.1", features = ["warp"] }
4041
prometheus = { workspace = true }

server/src/http.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
//! Http service
44
55
use std::{
6-
collections::HashMap, convert::Infallible, error::Error as StdError, net::IpAddr, sync::Arc,
7-
time::Duration,
6+
collections::HashMap, convert::Infallible, error::Error as StdError, fs::File, net::IpAddr,
7+
sync::Arc, thread, time::Duration,
88
};
99

1010
use analytic_engine::setup::OpenedWals;
@@ -194,6 +194,7 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
194194
.or(self.flush_memtable())
195195
.or(self.update_log_level())
196196
.or(self.heap_profile())
197+
.or(self.cpu_profile())
197198
.or(self.server_config())
198199
.or(self.stats())
199200
}
@@ -410,6 +411,40 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
410411
)
411412
}
412413

414+
// GET /debug/cpu_profile/{seconds}
415+
fn cpu_profile(
416+
&self,
417+
) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + Clone {
418+
warp::path!("debug" / "cpu_profile" / ..)
419+
.and(warp::path::param::<u64>())
420+
.and(warp::get())
421+
.and(self.with_context())
422+
.and_then(|duration_sec: u64, ctx: RequestContext| async move {
423+
let handle = ctx.runtime.spawn_blocking(move || -> Result<()> {
424+
let guard = pprof::ProfilerGuardBuilder::default()
425+
.frequency(100)
426+
.blocklist(&["libc", "libgcc", "pthread", "vdso"])
427+
.build()
428+
.box_err()
429+
.context(Internal)?;
430+
431+
thread::sleep(Duration::from_secs(duration_sec));
432+
433+
let report = guard.report().build().box_err().context(Internal)?;
434+
let file = File::create("/tmp/flamegraph.svg")
435+
.box_err()
436+
.context(Internal)?;
437+
report.flamegraph(file).box_err().context(Internal)?;
438+
Ok(())
439+
});
440+
let result = handle.await.context(JoinAsyncTask);
441+
match result {
442+
Ok(_) => Ok("ok"),
443+
Err(e) => Err(reject::custom(e)),
444+
}
445+
})
446+
}
447+
413448
// GET /debug/config
414449
fn server_config(
415450
&self,

0 commit comments

Comments
 (0)