mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
392 lines
9.8 KiB
TypeScript
392 lines
9.8 KiB
TypeScript
import { ReportConfig } from './reports.types'
|
|
import type { AnalyticsData, AnalyticsInterval } from '@/data/analytics/constants'
|
|
import { mapResponseToAnalyticsData } from '@/data/analytics/infra-monitoring-queries'
|
|
import {
|
|
getInfraMonitoringAttributes,
|
|
InfraMonitoringAttribute,
|
|
} from '@/data/analytics/infra-monitoring-query'
|
|
|
|
async function runInfraMonitoringQuery(
|
|
projectRef: string,
|
|
attribute: InfraMonitoringAttribute,
|
|
startDate: string,
|
|
endDate: string,
|
|
interval: AnalyticsInterval,
|
|
databaseIdentifier?: string
|
|
): Promise<AnalyticsData> {
|
|
const response = await getInfraMonitoringAttributes({
|
|
projectRef,
|
|
attributes: [attribute],
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier,
|
|
})
|
|
|
|
// Use shared mapping function that handles both single and multi-attribute response formats
|
|
const mapped = mapResponseToAnalyticsData(response, [attribute])
|
|
const analyticsData = mapped[attribute]
|
|
|
|
return {
|
|
data: analyticsData?.data ?? [],
|
|
format: analyticsData?.format,
|
|
yAxisLimit: analyticsData?.yAxisLimit,
|
|
total: analyticsData?.total,
|
|
totalGrouped: { [attribute]: analyticsData?.total },
|
|
} as AnalyticsData
|
|
}
|
|
|
|
export const realtimeReports = ({
|
|
projectRef,
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier,
|
|
}: {
|
|
projectRef: string
|
|
startDate: string
|
|
endDate: string
|
|
interval: AnalyticsInterval
|
|
databaseIdentifier?: string
|
|
}): ReportConfig[] => [
|
|
{
|
|
id: 'realtime_sum_connections_connected',
|
|
label: 'Connected Clients',
|
|
valuePrecision: 0,
|
|
hide: false,
|
|
showSumAsDefaultHighlight: false,
|
|
showNewBadge: true,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'line',
|
|
titleTooltip: 'Total number of connected realtime clients.',
|
|
dataProvider: async () => {
|
|
const data = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_sum_connections_connected',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_sum_connections_connected',
|
|
label: 'Connected Clients',
|
|
},
|
|
]
|
|
|
|
return { data: data?.data || [], attributes }
|
|
},
|
|
},
|
|
{
|
|
id: 'broadcast-events',
|
|
label: 'Broadcast Events',
|
|
valuePrecision: 0,
|
|
hide: false,
|
|
showNewBadge: true,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
titleTooltip: '',
|
|
dataProvider: async () => {
|
|
const { data } = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_channel_events',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const transformedData = data?.map((p) => ({
|
|
...p,
|
|
realtime_channel_events: Number(p.realtime_channel_events) || 0,
|
|
}))
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_channel_events',
|
|
label: 'Events',
|
|
},
|
|
]
|
|
|
|
return { data: transformedData || [], attributes }
|
|
},
|
|
},
|
|
|
|
{
|
|
id: 'presence-events',
|
|
label: 'Presence Events',
|
|
valuePrecision: 0,
|
|
hide: false,
|
|
showNewBadge: true,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
titleTooltip: '',
|
|
dataProvider: async () => {
|
|
const { data } = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_channel_presence_events',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const transformedData = data?.map((p) => ({
|
|
...p,
|
|
realtime_channel_presence_events: Number(p.realtime_channel_presence_events) || 0,
|
|
}))
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_channel_presence_events',
|
|
label: 'Events',
|
|
},
|
|
]
|
|
|
|
return { data: transformedData || [], attributes }
|
|
},
|
|
},
|
|
|
|
{
|
|
id: 'db-events',
|
|
label: 'Postgres Changes Events',
|
|
valuePrecision: 0,
|
|
hide: false,
|
|
showNewBadge: true,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
titleTooltip: '',
|
|
dataProvider: async () => {
|
|
const { data } = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_channel_db_events',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const transformedData = data?.map((p) => ({
|
|
...p,
|
|
realtime_channel_db_events: Number(p.realtime_channel_db_events) || 0,
|
|
}))
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_channel_db_events',
|
|
label: 'Events',
|
|
},
|
|
]
|
|
|
|
return { data: transformedData || [], attributes }
|
|
},
|
|
},
|
|
{
|
|
id: 'realtime_rate_of_channel_joins',
|
|
label: 'Rate of Channel Joins',
|
|
valuePrecision: 2,
|
|
hide: false,
|
|
showSumAsDefaultHighlight: false,
|
|
showTooltip: false,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'line',
|
|
titleTooltip: '',
|
|
dataProvider: async () => {
|
|
const data = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_channel_joins',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_channel_joins',
|
|
label: 'Channel Joins',
|
|
},
|
|
]
|
|
|
|
return { data: data?.data || [], attributes }
|
|
},
|
|
},
|
|
{
|
|
id: 'realtime_payload_size',
|
|
label: 'Message Payload Size',
|
|
valuePrecision: 2,
|
|
showNewBadge: true,
|
|
hide: false,
|
|
showSumAsDefaultHighlight: false,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'line',
|
|
titleTooltip: 'Median size of message payloads sent',
|
|
YAxisProps: {
|
|
width: 50,
|
|
tickFormatter: (value: number) => `${value}B`,
|
|
},
|
|
format: (value: unknown) => `${Number(value).toFixed(2)}B`,
|
|
dataProvider: async () => {
|
|
const data = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_payload_size',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_payload_size',
|
|
label: 'Median Payload Size (bytes)',
|
|
},
|
|
]
|
|
|
|
return { data: data?.data || [], attributes }
|
|
},
|
|
},
|
|
{
|
|
id: 'realtime_replication_connection_lag',
|
|
label: 'Broadcast From Database Replication Lag',
|
|
valuePrecision: 2,
|
|
showNewBadge: true,
|
|
hide: false,
|
|
showSumAsDefaultHighlight: false,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'line',
|
|
titleTooltip:
|
|
'Median time between database commit and broadcast when using broadcast from database.',
|
|
entitlement: 'realtime',
|
|
requiredPlan: 'Pro',
|
|
YAxisProps: {
|
|
width: 50,
|
|
tickFormatter: (value: number) => `${value}ms`,
|
|
},
|
|
format: (value: unknown) => `${Number(value).toFixed(2)}ms`,
|
|
dataProvider: async () => {
|
|
const data = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_replication_connection_lag',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_replication_connection_lag',
|
|
label: 'Median Replication Lag (ms)',
|
|
},
|
|
]
|
|
|
|
return { data: data?.data || [], attributes }
|
|
},
|
|
},
|
|
{
|
|
id: 'realtime_read_authorization_rls_execution_time',
|
|
label: '(Read) Private Channel Subscription RLS Execution Time',
|
|
valuePrecision: 2,
|
|
showNewBadge: true,
|
|
hide: false,
|
|
showSumAsDefaultHighlight: false,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'line',
|
|
titleTooltip:
|
|
'Execution median time of RLS (Row Level Security) to subscribe to a private channel',
|
|
entitlement: 'realtime',
|
|
requiredPlan: 'Pro',
|
|
YAxisProps: {
|
|
width: 50,
|
|
tickFormatter: (value: number) => `${value}ms`,
|
|
},
|
|
format: (value: unknown) => `${Number(value).toFixed(2)}ms`,
|
|
dataProvider: async () => {
|
|
const data = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_read_authorization_rls_execution_time',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_read_authorization_rls_execution_time',
|
|
label: 'RLS Execution Time (ms)',
|
|
},
|
|
]
|
|
|
|
return { data: data?.data || [], attributes }
|
|
},
|
|
},
|
|
{
|
|
id: 'realtime_write_authorization_rls_execution_time',
|
|
label: '(Write) Private Channel Subscription RLS Execution Time',
|
|
valuePrecision: 2,
|
|
showNewBadge: true,
|
|
hide: false,
|
|
showSumAsDefaultHighlight: false,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'line',
|
|
titleTooltip:
|
|
'Execution median time of RLS (Row Level Security) to publish to a private channel',
|
|
entitlement: 'realtime',
|
|
requiredPlan: 'Pro',
|
|
YAxisProps: {
|
|
width: 50,
|
|
tickFormatter: (value: number) => `${value}ms`,
|
|
},
|
|
format: (value: unknown) => `${Number(value).toFixed(2)}ms`,
|
|
dataProvider: async () => {
|
|
const data = await runInfraMonitoringQuery(
|
|
projectRef,
|
|
'realtime_write_authorization_rls_execution_time',
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier
|
|
)
|
|
|
|
const attributes = [
|
|
{
|
|
attribute: 'realtime_write_authorization_rls_execution_time',
|
|
label: 'RLS Execution Time (ms)',
|
|
},
|
|
]
|
|
|
|
return { data: data?.data || [], attributes }
|
|
},
|
|
},
|
|
]
|