mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-15 17:32:56 +00:00
jemalloc profiling
This commit is contained in:
@@ -21,6 +21,7 @@ base64.workspace = true
|
||||
bstr.workspace = true
|
||||
bytes = { workspace = true, features = ["serde"] }
|
||||
camino.workspace = true
|
||||
camino-tempfile.workspace = true
|
||||
chrono.workspace = true
|
||||
clap.workspace = true
|
||||
consumption_metrics.workspace = true
|
||||
@@ -78,7 +79,7 @@ subtle.workspace = true
|
||||
sync_wrapper.workspace = true
|
||||
task-local-extensions.workspace = true
|
||||
thiserror.workspace = true
|
||||
tikv-jemallocator.workspace = true
|
||||
tikv-jemallocator = { workspace = true, features = ["profiling"] }
|
||||
tikv-jemalloc-ctl = { workspace = true, features = ["use_std"] }
|
||||
tokio-postgres.workspace = true
|
||||
tokio-rustls.workspace = true
|
||||
@@ -102,7 +103,6 @@ redis.workspace = true
|
||||
workspace_hack.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
camino-tempfile.workspace = true
|
||||
fallible-iterator.workspace = true
|
||||
rcgen.workspace = true
|
||||
rstest.workspace = true
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
use anyhow::{anyhow, bail};
|
||||
use camino::Utf8PathBuf;
|
||||
use camino_tempfile::Utf8TempDir;
|
||||
use hyper::{header::CONTENT_TYPE, Body, Request, Response, StatusCode};
|
||||
use measured::{text::BufferedTextEncoder, MetricGroup};
|
||||
use metrics::NeonMetrics;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
ffi::CString,
|
||||
net::TcpListener,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use tikv_jemalloc_ctl::{opt, prof};
|
||||
use tracing::{info, info_span};
|
||||
use utils::http::{
|
||||
endpoint::{self, request_span},
|
||||
@@ -21,18 +26,44 @@ async fn status_handler(_: Request<Body>) -> Result<Response<Body>, ApiError> {
|
||||
json_response(StatusCode::OK, "")
|
||||
}
|
||||
|
||||
async fn prof_dump(_: Request<Body>) -> Result<Response<Body>, ApiError> {
|
||||
static PROF_MIB: Lazy<prof::dump_mib> =
|
||||
Lazy::new(|| prof::dump::mib().expect("could not create prof.dump MIB"));
|
||||
static PROF_DIR: Lazy<Utf8TempDir> =
|
||||
Lazy::new(|| camino_tempfile::tempdir().expect("could not create tempdir"));
|
||||
static PROF_FILE: Lazy<Utf8PathBuf> = Lazy::new(|| PROF_DIR.path().join("prof.dump"));
|
||||
static PROF_FILE0: Lazy<CString> = Lazy::new(|| CString::new(PROF_FILE.as_str()).unwrap());
|
||||
static DUMP_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
tokio::task::spawn_blocking(|| {
|
||||
let _guard = DUMP_LOCK.lock();
|
||||
PROF_MIB
|
||||
.write(&PROF_FILE0)
|
||||
.expect("could not trigger prof.dump");
|
||||
let prof_dump = std::fs::read_to_string(&*PROF_FILE).expect("could not open prof.dump");
|
||||
|
||||
Response::new(Body::from(prof_dump))
|
||||
})
|
||||
.await
|
||||
.map_err(|e| ApiError::InternalServerError(e.into()))
|
||||
}
|
||||
|
||||
fn make_router(metrics: AppMetrics) -> RouterBuilder<hyper::Body, ApiError> {
|
||||
let state = Arc::new(Mutex::new(PrometheusHandler {
|
||||
encoder: BufferedTextEncoder::new(),
|
||||
metrics,
|
||||
}));
|
||||
|
||||
info!(enabled = opt::prof::read().unwrap(), "jemalloc profiling");
|
||||
prof::active::write(true).unwrap();
|
||||
|
||||
endpoint::make_router()
|
||||
.get("/metrics", move |r| {
|
||||
let state = state.clone();
|
||||
request_span(r, move |b| prometheus_metrics_handler(b, state))
|
||||
})
|
||||
.get("/v1/status", status_handler)
|
||||
.get("/v1/jemalloc/prof.dump", prof_dump)
|
||||
}
|
||||
|
||||
pub async fn task_main(
|
||||
|
||||
Reference in New Issue
Block a user