usePostgrestOverviewMetrics.ts101 lines · main
1import { useQuery } from '@tanstack/react-query'
2
3import type { LogsBarChartDatum } from '../ProjectHome/ProjectUsage.metrics'
4import { get } from '@/data/fetchers'
5
6type PostgrestMetricsVariables = {
7 projectRef: string
8 startDate: string
9 endDate: string
10 interval: '1hr' | '1day' | '7day'
11}
12
13const getIntervalTrunc = (interval: '1hr' | '1day' | '7day') => {
14 switch (interval) {
15 case '1hr':
16 return 'minute' // 1-minute buckets for 1 hour
17 case '1day':
18 return 'hour' // 1-hour buckets for 1 day
19 case '7day':
20 return 'day' // 1-day buckets for 7 days
21 default:
22 return 'hour'
23 }
24}
25
26const POSTGREST_METRICS_SQL = (interval: '1hr' | '1day' | '7day') => {
27 const truncInterval = getIntervalTrunc(interval)
28
29 return `
30 -- postgrest-overview-metrics
31 select
32 cast(timestamp_trunc(t.timestamp, ${truncInterval}) as datetime) as timestamp,
33 countif(response.status_code < 300) as ok_count,
34 countif(response.status_code >= 300 and response.status_code < 400) as warning_count,
35 countif(response.status_code >= 400) as error_count
36 FROM edge_logs t
37 cross join unnest(metadata) as m
38 cross join unnest(m.response) as response
39 cross join unnest(m.request) as request
40 WHERE
41 request.path like '/rest/%'
42 GROUP BY
43 timestamp
44 ORDER BY
45 timestamp ASC
46 `
47}
48
49type MetricsRow = {
50 timestamp: string
51 ok_count: number
52 warning_count: number
53 error_count: number
54}
55
56async function fetchPostgrestMetrics(
57 { projectRef, startDate, endDate, interval }: PostgrestMetricsVariables,
58 signal?: AbortSignal
59) {
60 const sql = POSTGREST_METRICS_SQL(interval)
61
62 const { data, error } = await get(`/platform/projects/{ref}/analytics/endpoints/logs.all`, {
63 params: {
64 path: { ref: projectRef },
65 query: {
66 sql,
67 iso_timestamp_start: startDate,
68 iso_timestamp_end: endDate,
69 },
70 },
71 signal,
72 })
73
74 if (error || data?.error) {
75 throw error || data?.error
76 }
77
78 return (data?.result || []) as MetricsRow[]
79}
80
81export const usePostgrestOverviewMetrics = (
82 { projectRef, startDate, endDate, interval }: PostgrestMetricsVariables,
83 options?: { enabled?: boolean }
84) => {
85 return useQuery({
86 queryKey: ['postgrest-overview-metrics', projectRef, startDate, endDate, interval],
87 queryFn: ({ signal }) =>
88 fetchPostgrestMetrics({ projectRef, startDate, endDate, interval }, signal),
89 enabled: (options?.enabled ?? true) && Boolean(projectRef),
90 staleTime: 1000 * 60,
91 })
92}
93
94export const transformPostgrestMetrics = (rows: MetricsRow[]): LogsBarChartDatum[] => {
95 return rows.map((row) => ({
96 timestamp: row.timestamp,
97 ok_count: row.ok_count,
98 warning_count: row.warning_count,
99 error_count: row.error_count,
100 }))
101}