usePostgrestOverviewMetrics.ts 2.7 KB

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