Skip to content

Commit 2808931

Browse files
authored
Chore/refactor unified logs infinite queries (supabase#36598)
* Split unified logs count into its own infinite query and refactor main UI to use that new query * Split unified logs into its own infinite query and refactor main UI to use that new query * Shift useChartData into unified-logs-chart-query, and refactor main UI to use that new query * Rename unified-logs-query to unified-logs-infinite-query * Remove uuid and live params from query string in react queries for unified logs
1 parent ea9cfe1 commit 2808931

File tree

10 files changed

+535
-660
lines changed

10 files changed

+535
-660
lines changed

apps/studio/components/interfaces/UnifiedLogs/QueryOptions.ts

Lines changed: 0 additions & 617 deletions
This file was deleted.

apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.queries.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import dayjs from 'dayjs'
22

3-
import { SearchParamsType } from './UnifiedLogs.types'
3+
import { QuerySearchParamsType, SearchParamsType } from './UnifiedLogs.types'
44

55
// Pagination and control parameters
66
const PAGINATION_PARAMS = ['sort', 'start', 'size', 'uuid', 'cursor', 'direction', 'live'] as const
@@ -17,7 +17,7 @@ const BASE_CONDITIONS_EXCLUDED_PARAMS = [...PAGINATION_PARAMS, 'date', 'level']
1717
* @param search SearchParamsType object containing query parameters
1818
* @returns Object with whereConditions array and formatted WHERE clause
1919
*/
20-
const buildQueryConditions = (search: SearchParamsType) => {
20+
const buildQueryConditions = (search: QuerySearchParamsType) => {
2121
const whereConditions: string[] = []
2222

2323
// Process all search parameters for filtering
@@ -465,7 +465,7 @@ WITH unified_logs AS (
465465
/**
466466
* Unified logs SQL query
467467
*/
468-
export const getUnifiedLogsQuery = (search: SearchParamsType): string => {
468+
export const getUnifiedLogsQuery = (search: QuerySearchParamsType): string => {
469469
// Use the buildQueryConditions helper
470470
const { finalWhere } = buildQueryConditions(search)
471471

@@ -497,7 +497,7 @@ ${finalWhere}
497497
* Get a count query for the total logs within the timeframe
498498
* Also returns facets for all filter dimensions
499499
*/
500-
export const getLogsCountQuery = (search: SearchParamsType): string => {
500+
export const getLogsCountQuery = (search: QuerySearchParamsType): string => {
501501
// Use the buildQueryConditions helper
502502
const { finalWhere } = buildQueryConditions(search)
503503

@@ -542,9 +542,9 @@ GROUP BY method
542542
* Enhanced logs chart query with dynamic bucketing based on time range
543543
* Incorporates dynamic bucketing from the older implementation
544544
*/
545-
export const getLogsChartQuery = (search: SearchParamsType | Record<string, any>): string => {
545+
export const getLogsChartQuery = (search: QuerySearchParamsType): string => {
546546
// Use the buildQueryConditions helper
547-
const { finalWhere } = buildQueryConditions(search as SearchParamsType)
547+
const { finalWhere } = buildQueryConditions(search)
548548

549549
// Determine appropriate bucketing level based on time range
550550
const truncationLevel = calculateChartBucketing(search)

apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.tsx

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useInfiniteQuery } from '@tanstack/react-query'
21
import {
32
ColumnFiltersState,
43
getCoreRowModel,
@@ -30,6 +29,9 @@ import { LiveRow } from 'components/ui/DataTable/LiveRow'
3029
import { DataTableProvider } from 'components/ui/DataTable/providers/DataTableProvider'
3130
import { RefreshButton } from 'components/ui/DataTable/RefreshButton'
3231
import { TimelineChart } from 'components/ui/DataTable/TimelineChart'
32+
import { useUnifiedLogsChartQuery } from 'data/logs/unified-logs-chart-query'
33+
import { useUnifiedLogsCountQuery } from 'data/logs/unified-logs-count-query'
34+
import { useUnifiedLogsInfiniteQuery } from 'data/logs/unified-logs-infinite-query'
3335
import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage'
3436
import {
3537
ChartConfig,
@@ -46,10 +48,10 @@ import {
4648
import { COLUMNS } from './components/Columns'
4749
import { MemoizedDataTableSheetContent } from './components/DataTableSheetContent'
4850
import { FunctionLogsTab } from './components/FunctionLogsTab'
49-
import { dataOptions, useChartData } from './QueryOptions'
5051
import { CHART_CONFIG, SEARCH_PARAMS_PARSER } from './UnifiedLogs.constants'
5152
import { filterFields as defaultFilterFields, sheetFields } from './UnifiedLogs.fields'
5253
import { useLiveMode, useResetFocus } from './UnifiedLogs.hooks'
54+
import { QuerySearchParamsType } from './UnifiedLogs.types'
5355
import { getFacetedUniqueValues, getLevelRowClassName, logEventBus } from './UnifiedLogs.utils'
5456

5557
// Debug mode flag - set to true to enable detailed logs
@@ -84,29 +86,47 @@ export const UnifiedLogs = () => {
8486
[]
8587
)
8688

87-
// [Joshen] This needs to move to the data folder to follow our proper RQ structure
88-
const { data, isFetching, isLoading, fetchNextPage, hasNextPage, fetchPreviousPage, refetch } =
89-
// @ts-ignore
90-
useInfiniteQuery(dataOptions(search, projectRef ?? ''))
89+
// Create a stable query key object by removing nulls/undefined, uuid, and live
90+
// Mainly to prevent the react queries from unnecessarily re-fetching
91+
const searchParameters = Object.entries(search).reduce(
92+
(acc, [key, value]) => {
93+
if (!['uuid', 'live'].includes(key) && value !== null && value !== undefined) {
94+
acc[key] = value
95+
}
96+
return acc
97+
},
98+
{} as Record<string, any>
99+
) as QuerySearchParamsType
100+
101+
const {
102+
data: unifiedLogsData,
103+
isLoading,
104+
isFetching,
105+
hasNextPage,
106+
refetch,
107+
fetchNextPage,
108+
fetchPreviousPage,
109+
} = useUnifiedLogsInfiniteQuery({ projectRef, search: searchParameters })
110+
const { data: counts } = useUnifiedLogsCountQuery({ projectRef, search: searchParameters })
111+
const { data: unifiedLogsChart = [] } = useUnifiedLogsChartQuery({
112+
projectRef,
113+
search: searchParameters,
114+
})
91115

92116
const flatData = useMemo(() => {
93-
return data?.pages?.flatMap((page) => page.data ?? []) ?? []
94-
}, [data?.pages])
117+
return unifiedLogsData?.pages?.flatMap((page) => page.data ?? []) ?? []
118+
}, [unifiedLogsData?.pages])
95119
const liveMode = useLiveMode(flatData)
96120

97-
// Add the chart data query for the entire time period
98-
const { data: chartDataResult } = useChartData(search, projectRef ?? '')
99-
100121
// REMINDER: meta data is always the same for all pages as filters do not change(!)
101-
const lastPage = data?.pages?.[data?.pages.length - 1]
122+
const lastPage = unifiedLogsData?.pages?.[unifiedLogsData?.pages.length - 1]
123+
102124
// Use the totalCount from chartDataResult which gives us the actual count of logs in the time period
103125
// instead of the hardcoded 10000 value
104-
const totalDBRowCount = chartDataResult?.totalCount || lastPage?.meta?.totalRowCount
126+
const totalDBRowCount = counts?.totalRowCount
105127
const filterDBRowCount = lastPage?.meta?.filterRowCount
106-
const metadata = lastPage?.meta?.metadata
107-
// Use chart data from the separate query if available, fallback to the default
108-
const chartData = chartDataResult?.chartData || lastPage?.meta?.chartData
109-
const facets = lastPage?.meta?.facets
128+
129+
const facets = counts?.facets
110130
const totalFetched = flatData?.length
111131

112132
// Create a filtered version of the chart config based on selected levels
@@ -152,18 +172,13 @@ export const UnifiedLogs = () => {
152172
getFacetedRowModel: getFacetedRowModel(),
153173
getFacetedUniqueValues: getTTableFacetedUniqueValues(),
154174
getFacetedMinMaxValues: getTTableFacetedMinMaxValues(),
155-
// Here, manually override the filter function for the level column
156-
// to prevent client-side filtering since it's already filtered on the server
157-
// Always return true to pass all level values
158-
// columnFilterFns: { level: () => true },
159-
// debugAll: process.env.NEXT_PUBLIC_TABLE_DEBUG === 'true',
160175
})
161176

162177
const selectedRow = useMemo(() => {
163178
if ((isLoading || isFetching) && !flatData.length) return
164179
const selectedRowKey = Object.keys(rowSelection)?.[0]
165180
return table.getCoreRowModel().flatRows.find((row) => row.id === selectedRowKey)
166-
}, [rowSelection, table, isLoading, isFetching, flatData])
181+
}, [rowSelection, flatData])
167182

168183
const selectedRowKey = Object.keys(rowSelection)?.[0]
169184

@@ -247,7 +262,6 @@ export const UnifiedLogs = () => {
247262
// eslint-disable-next-line react-hooks/exhaustive-deps
248263
}, [sorting])
249264

250-
// TODO: can only share uuid within the first batch
251265
useEffect(() => {
252266
if (isLoading || isFetching) return
253267
if (Object.keys(rowSelection)?.length && !selectedRow) {
@@ -283,7 +297,6 @@ export const UnifiedLogs = () => {
283297
enableColumnOrdering={true}
284298
isLoading={isFetching || isLoading}
285299
getFacetedUniqueValues={getFacetedUniqueValues(facets)}
286-
// getFacetedMinMaxValues={getFacetedMinMaxValues(facets)}
287300
>
288301
<DataTableSideBarLayout topBarHeight={topBarHeight}>
289302
<FilterSideBar />
@@ -303,7 +316,7 @@ export const UnifiedLogs = () => {
303316
]}
304317
/>
305318
<TimelineChart
306-
data={chartData ?? []}
319+
data={unifiedLogsChart}
307320
className="-mb-2"
308321
columnId="timestamp"
309322
chartConfig={filteredChartConfig}
@@ -394,8 +407,7 @@ export const UnifiedLogs = () => {
394407
totalRows: totalDBRowCount ?? 0,
395408
filterRows: filterDBRowCount ?? 0,
396409
totalRowsFetched: totalFetched ?? 0,
397-
currentPercentiles: metadata?.currentPercentiles ?? ({} as any),
398-
...metadata,
410+
currentPercentiles: {} as any,
399411
}}
400412
/>
401413
</TabsContent>

apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.types.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,10 @@ export type LogsMeta = {
2323
currentPercentiles: Record<Percentile, number>
2424
}
2525

26-
export type UnifiedLogsMeta = {
27-
logTypeCounts: Record<UnifiedLogSchema['log_type'], number>
28-
currentPercentiles: Record<string, number>
29-
}
30-
3126
export type PageParam = { cursor: number; direction: 'next' | 'prev' }
3227

3328
export type SearchParamsType = inferParserType<typeof SEARCH_PARAMS_PARSER>
29+
export type QuerySearchParamsType = Omit<SearchParamsType, 'uuid' | 'live'>
3430

3531
export type SearchParams = {
3632
[key: string]: string | string[] | undefined

apps/studio/components/interfaces/UnifiedLogs/components/DataTableSheetContent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Table } from '@tanstack/react-table'
2-
import { memo } from 'react'
2+
import { HTMLAttributes, memo } from 'react'
33

44
import { DataTableFilterField } from 'components/ui/DataTable/DataTable.types'
55
import { DataTableSheetRowAction } from 'components/ui/DataTable/DataTableSheetRowAction'
@@ -30,7 +30,7 @@ const SheetDetailsContentSkeleton = <TData, TMeta>({
3030
)
3131
}
3232

33-
interface DataTableSheetContentProps<TData, TMeta> extends React.HTMLAttributes<HTMLDListElement> {
33+
interface DataTableSheetContentProps<TData, TMeta> extends HTMLAttributes<HTMLDListElement> {
3434
data?: TData
3535
table: Table<TData>
3636
fields: SheetField<TData, TMeta>[]

apps/studio/components/ui/DataTable/providers/DataTableProvider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type {
77
Table,
88
VisibilityState,
99
} from '@tanstack/react-table'
10-
import { createContext, useContext, useMemo } from 'react'
10+
import { createContext, ReactNode, useContext, useMemo } from 'react'
1111

1212
import { DataTableFilterField } from '../DataTable.types'
1313
import { ControlsProvider } from './ControlsProvider'
@@ -45,7 +45,7 @@ export function DataTableProvider<TData, TValue>({
4545
...props
4646
}: Partial<DataTableStateContextType> &
4747
DataTableBaseContextType<TData, TValue> & {
48-
children: React.ReactNode
48+
children: ReactNode
4949
}) {
5050
const value = useMemo(
5151
() => ({

apps/studio/data/logs/keys.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { QuerySearchParamsType } from 'components/interfaces/UnifiedLogs/UnifiedLogs.types'
2+
3+
export const logsKeys = {
4+
unifiedLogsInfinite: (
5+
projectRef: string | undefined,
6+
searchParams: QuerySearchParamsType | undefined
7+
) =>
8+
[
9+
'projects',
10+
projectRef,
11+
'unified-logs',
12+
'logs-data',
13+
...(searchParams ? [searchParams].filter(Boolean) : []),
14+
] as const,
15+
unifiedLogsCount: (
16+
projectRef: string | undefined,
17+
searchParams: QuerySearchParamsType | undefined
18+
) =>
19+
[
20+
'projects',
21+
projectRef,
22+
'unified-logs',
23+
'count-data',
24+
...(searchParams ? [searchParams].filter(Boolean) : []),
25+
] as const,
26+
unifiedLogsChart: (
27+
projectRef: string | undefined,
28+
searchParams: QuerySearchParamsType | undefined
29+
) =>
30+
[
31+
'projects',
32+
projectRef,
33+
'unified-logs',
34+
'chart-data',
35+
...(searchParams ? [searchParams].filter(Boolean) : []),
36+
] as const,
37+
}

0 commit comments

Comments
 (0)