fixed query overlay

This commit is contained in:
Jonathan Summers-Muir authored and kemal committed 2025-08-08 11:21:24 +01:00
1 parent 81e2e0d998
commit 32abb0a7e2
3 files changed
+64 -36

No files matched your search

@@ -88,7 +88,8 @@ export function MetricsChart({
if (metric === 'query_latency') {
// Create the baseline chart data from the metrics
const chartData = data.map((point) => {
const timestamp = dayjs(point.timestamp).format('HH:mm')
// Keep the original timestamp to maintain 5-minute intervals
const timestamp = point.timestamp
return {
timestamp,
p50: point.p50,
@@ -102,7 +103,7 @@ export function MetricsChart({
// Sort chart data by timestamp
chartData.sort((a, b) => {
return dayjs(a.timestamp, 'HH:mm').diff(dayjs(b.timestamp, 'HH:mm'))
return dayjs(a.timestamp).diff(dayjs(b.timestamp))
})
// If we have query latency data, add it to the chart
@@ -110,17 +111,32 @@ export function MetricsChart({
// Create a map of timestamps to query latency values
const queryLatencyMap = new Map<string, number>()
queryLatencyData.forEach((point) => {
const timestamp = dayjs(point.timestamp).format('HH:mm')
queryLatencyMap.set(timestamp, point.value || 0)
queryLatencyMap.set(point.timestamp, point.value || 0)
})
// Add query latency data to each chart data point
// Points without data will keep their 0 value
chartData.forEach((point) => {
if (queryLatencyMap.has(point.timestamp)) {
point.query_latency = queryLatencyMap.get(point.timestamp)!
}
})
// Add any missing query latency points
queryLatencyData.forEach((point) => {
if (!chartData.find((d) => d.timestamp === point.timestamp)) {
chartData.push({
timestamp: point.timestamp,
p50: 0,
p95: 0,
p99: 0,
p99_9: 0,
query_latency: point.value || 0,
})
}
})
// Re-sort chart data by timestamp
chartData.sort((a, b) => dayjs(a.timestamp).diff(dayjs(b.timestamp)))
}
const config = {
@@ -252,6 +268,7 @@ export function MetricsChart({
tickLine={false}
axisLine={false}
tickMargin={8}
tickFormatter={(value) => dayjs(value).format('HH:mm')}
/>
<YAxis />
<ChartTooltip
@@ -18,7 +18,7 @@ export type QueryInsightsMetric = {
}
export type QueryInsightsQuery = {
query_id: string
query_id: number
query: string
total_time: number
calls: number
@@ -28,6 +28,7 @@ export type QueryInsightsQuery = {
mean_exec_time: number
database: string
timestamp: string
cmd_type_text: string
}
export type QueryInsightsMetrics = {
@@ -53,25 +54,27 @@ const getMetricsSql = (metric: string, startTime: string, endTime: string) => {
return /* SQL */ `
SELECT
bucket_start_time as timestamp,
SUM(rows_retrieved) as value,
SUM(rows) / 300 as value, -- Convert to per-second rate (5 mins = 300 seconds)
datname as database
FROM pg_stat_monitor
WHERE bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
WHERE bucket_start_time >= '${startTime}'::timestamptz
AND bucket_start_time <= '${endTime}'::timestamptz
AND bucket_done = true -- Only include completed buckets
GROUP BY bucket_start_time, datname
ORDER BY bucket_start_time ASC
ORDER BY timestamp ASC
`
case 'rows_written':
return /* SQL */ `
SELECT
bucket_start_time as timestamp,
SUM(rows_retrieved) as value,
SUM(rows) / 300 as value, -- Convert to per-second rate (5 mins = 300 seconds)
datname as database
FROM pg_stat_monitor
WHERE bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
WHERE bucket_start_time >= '${startTime}'::timestamptz
AND bucket_start_time <= '${endTime}'::timestamptz
AND bucket_done = true -- Only include completed buckets
GROUP BY bucket_start_time, datname
ORDER BY bucket_start_time ASC
ORDER BY timestamp ASC
`
case 'query_latency':
return /* SQL */ `
@@ -83,54 +86,59 @@ const getMetricsSql = (metric: string, startTime: string, endTime: string) => {
percentile_cont(0.999) WITHIN GROUP (ORDER BY mean_exec_time) as p99_9,
datname as database
FROM pg_stat_monitor
WHERE bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
WHERE bucket_start_time >= '${startTime}'::timestamptz
AND bucket_start_time <= '${endTime}'::timestamptz
AND bucket_done = true -- Only include completed buckets
GROUP BY bucket_start_time, datname
ORDER BY bucket_start_time ASC
ORDER BY timestamp ASC
`
case 'queries_per_second':
return /* SQL */ `
SELECT
bucket_start_time as timestamp,
COUNT(*) as value,
COUNT(*) / 300.0 as value, -- Convert to per-second rate (5 mins = 300 seconds)
datname as database
FROM pg_stat_monitor
WHERE bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
WHERE bucket_start_time >= '${startTime}'::timestamptz
AND bucket_start_time <= '${endTime}'::timestamptz
AND bucket_done = true -- Only include completed buckets
GROUP BY bucket_start_time, datname
ORDER BY bucket_start_time ASC
ORDER BY timestamp ASC
`
default:
return /* SQL */ `
SELECT
bucket_start_time as timestamp,
SUM(rows_retrieved) as value,
SUM(rows) / 300 as value, -- Convert to per-second rate (5 mins = 300 seconds)
datname as database
FROM pg_stat_monitor
WHERE bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
WHERE bucket_start_time >= '${startTime}'::timestamptz
AND bucket_start_time <= '${endTime}'::timestamptz
AND bucket_done = true -- Only include completed buckets
GROUP BY bucket_start_time, datname
ORDER BY bucket_start_time ASC
ORDER BY timestamp ASC
`
}
}
const getQueriesSql = (startTime: string, endTime: string) => /* SQL */ `
SELECT
SELECT
queryid as query_id,
query,
COALESCE(MAX(top_query), MAX(query)) as query,
SUM(total_exec_time) as total_time,
SUM(calls) as calls,
SUM(rows_retrieved) as rows,
SUM(rows) as rows,
SUM(shared_blks_read) as shared_blks_read,
SUM(shared_blks_hit) as shared_blks_hit,
AVG(mean_exec_time) as mean_exec_time,
datname as database,
MAX(bucket_start_time) as timestamp
SUM(total_exec_time) / NULLIF(SUM(calls), 0) as mean_exec_time,
STRING_AGG(DISTINCT datname, ', ') as database,
MAX(bucket_start_time) as timestamp,
MAX(get_cmd_type(cmd_type)) as cmd_type_text
FROM pg_stat_monitor
WHERE bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
GROUP BY queryid, query, datname
AND bucket_done = true -- Only include completed buckets
GROUP BY queryid
ORDER BY SUM(calls) DESC
LIMIT 100
`
@@ -20,12 +20,14 @@ const getSingleQueryLatencySql = (
SELECT
bucket_start_time as timestamp,
mean_exec_time as value,
calls,
datname as database
FROM pg_stat_monitor
WHERE queryid = '${queryId}'
AND bucket_start_time >= '${startTime}'
AND bucket_start_time <= '${endTime}'
ORDER BY bucket_start_time ASC
WHERE bucket_start_time >= '${startTime}'::timestamptz
AND bucket_start_time <= '${endTime}'::timestamptz
AND bucket_done = true -- Only include completed buckets
AND queryid = ${queryId}::bigint
ORDER BY timestamp ASC
`
export function useSingleQueryLatency(
@@ -46,6 +48,7 @@ export function useSingleQueryLatency(
sql: getSingleQueryLatencySql(queryId, startTime, endTime),
})
console.log('Chart data points:', result)
return result as QueryInsightsMetric[]
},
enabled: !!queryId && !!projectRef,