Return all columns from pg_stat_statements

This commit is contained in:
Alexey Kondratov
2022-09-29 18:40:54 +03:00
parent d9e14fdcfb
commit 4b5cf917e5
3 changed files with 25 additions and 23 deletions

View File

@@ -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);

View File

@@ -49,7 +49,6 @@ pub struct ComputeNode {
/// to allow HTTP API server to serve status requests, while configuration
/// is in progress.
pub state: RwLock<ComputeState>,
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<InsightsRow>,
@@ -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<InsightsRow> = Vec::new();
pub async fn collect_insights(&self) -> String {
let mut result_rows: Vec<String> = 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(","))
}
}

View File

@@ -46,11 +46,11 @@ async fn routes(req: Request<Body>, compute: Arc<ComputeNode>) -> Response<Body>
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