|
3 | 3 | //! Http service
|
4 | 4 |
|
5 | 5 | 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, |
8 | 8 | };
|
9 | 9 |
|
10 | 10 | use analytic_engine::setup::OpenedWals;
|
@@ -194,6 +194,7 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
|
194 | 194 | .or(self.flush_memtable())
|
195 | 195 | .or(self.update_log_level())
|
196 | 196 | .or(self.heap_profile())
|
| 197 | + .or(self.cpu_profile()) |
197 | 198 | .or(self.server_config())
|
198 | 199 | .or(self.stats())
|
199 | 200 | }
|
@@ -410,6 +411,40 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
|
410 | 411 | )
|
411 | 412 | }
|
412 | 413 |
|
| 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 | + |
413 | 448 | // GET /debug/config
|
414 | 449 | fn server_config(
|
415 | 450 | &self,
|
|
0 commit comments