diff --git a/compute_tools/src/bin/compute_ctl.rs b/compute_tools/src/bin/compute_ctl.rs index 02ee9ad9f6..fc5bbc5fd2 100644 --- a/compute_tools/src/bin/compute_ctl.rs +++ b/compute_tools/src/bin/compute_ctl.rs @@ -26,7 +26,6 @@ //! -b /usr/local/bin/postgres //! ``` //! -use std::sync::atomic::AtomicU64; use std::fs::File; use std::panic; use std::path::Path; @@ -142,7 +141,6 @@ fn main() -> Result<()> { pageserver_connstr, metrics: ComputeMetrics::new(), state: RwLock::new(ComputeState::new()), - insights_count: AtomicU64::new(0), }; let compute = Arc::new(compute_state); diff --git a/compute_tools/src/compute.rs b/compute_tools/src/compute.rs index ccda9933e7..027c2c2354 100644 --- a/compute_tools/src/compute.rs +++ b/compute_tools/src/compute.rs @@ -49,7 +49,6 @@ pub struct ComputeNode { /// to allow HTTP API server to serve status requests, while configuration /// is in progress. pub state: RwLock, - pub insights_count: AtomicU64, } #[derive(Debug, Serialize)] @@ -59,7 +58,7 @@ pub struct InsightsRow { pub mean_runtime: String, } -#[derive (Serialize)] +#[derive(Serialize)] pub struct Insights { count: u64, statements: Vec, @@ -368,10 +367,8 @@ impl ComputeNode { self.run() } - pub async fn collect_insights(&self) -> Insights { - let prev = self.insights_count.fetch_add(1, Ordering::Relaxed); - - let mut result_rows: Vec = Vec::new(); + pub async fn collect_insights(&self) -> String { + let mut result_rows: Vec = Vec::new(); let connect_result = tokio_postgres::connect(self.connstr.as_str(), NoTls).await; let (client, connection) = connect_result.unwrap(); tokio::spawn(async move { @@ -379,24 +376,31 @@ impl ComputeNode { eprintln!("connection error: {}", e); } }); - for message in (client.simple_query(" -SELECT query, total_exec_time, mean_exec_time -FROM pg_stat_statements -ORDER BY total_exec_time DESC LIMIT 100").await).unwrap().iter() { + for message in (client + .simple_query( + " +SELECT + row_to_json(pg_stat_statements) +FROM + pg_stat_statements +WHERE + userid != 'cloud_admin'::regrole::oid +ORDER BY + (mean_exec_time + mean_plan_time) DESC +LIMIT 100", + ) + .await) + .unwrap() + .iter() + { match message { postgres::SimpleQueryMessage::Row(row) => { - result_rows.push(InsightsRow { - query: row.get(0).unwrap().to_string(), - total_runtime: row.get(1).unwrap().to_string(), - mean_runtime: row.get(2).unwrap().to_string(), - }); + result_rows.push(row.get(0).unwrap().to_string()); } _ => {} } } - return Insights { - count: prev + 1, - statements: result_rows, - }; + + format!("{{\"pg_stat_statements\": [{}]}}", result_rows.join(",")) } } diff --git a/compute_tools/src/http/api.rs b/compute_tools/src/http/api.rs index 559de99253..8adb2bd8cc 100644 --- a/compute_tools/src/http/api.rs +++ b/compute_tools/src/http/api.rs @@ -46,11 +46,11 @@ async fn routes(req: Request, compute: Arc) -> Response Response::new(Body::from(serde_json::to_string(&compute.metrics).unwrap())) } - // Collect pg stat metrics + // Collect Postgres current usage insights (&Method::GET, "/insights") => { info!("serving /insights GET request"); let insights = compute.collect_insights().await; - Response::new(Body::from(serde_json::to_string(&insights).unwrap())) + Response::new(Body::from(insights)) } // DEPRECATED, use POST instead