mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 10:25:06 +03:00
## Problem
The observability overview page fetched service health data by making
six separate calls to the generic \`logs.all\` endpoint with
hand-crafted SQL (via \`genChartQuery\`). This coupled the overview to
SQL internals and missed out on the purpose-built \`service-health\`
endpoint that accepts structured \`lql\` filters and a \`granularity\`
parameter.
## Fix
- Added \`/platform/projects/{ref}/analytics/endpoints/service-health\`
to \`platform.d.ts\`, including the \`ProjectServiceHealthResponse\`
schema and \`UsageApiController_getProjectServiceHealth\` operation.
- Created \`apps/studio/data/analytics/service-health-query.ts\` with a
\`getServiceHealth\` fetch function and \`useServiceHealthQuery\` hook
following the same pattern as other analytics query files.
- Added a \`serviceHealth\` key factory to
\`apps/studio/data/analytics/keys.ts\`.
- Rewrote \`useServiceHealthMetrics.ts\` to call the new endpoint per
service using \`lql\` selectors (\`s:postgres_logs\`, \`s:auth_logs\`,
etc.) and a \`granularity\` value derived from the selected interval
(\`1hr\` -> \`minute\`, \`1day\` -> \`hour\`, \`7day\` -> \`day\`). The
timeseries normalisation and chart data pipeline is unchanged.
- Updated the refresh handler in \`ObservabilityOverview.tsx\` to
invalidate the new query key prefix and removed the now-unused
\`postgrest-overview-metrics\` invalidation.
## How to test
- Navigate to a project's Observability > Overview page.
- Verify that the Service Health table loads data for all six services
(Database, Auth, Edge Functions, Realtime, Storage, Data API).
- Switch between the 1hr, 1day, and 7day interval selectors and confirm
the charts update.
- Click the Refresh button and confirm the charts reload.
- Click a bar in any chart and confirm navigation to the corresponding
logs page scoped to that time window.
- Confirm no regressions in the Database Infrastructure section (CPU,
RAM, disk, connections).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Centralized service‑health fetching for consistent cross‑service
metrics and improved charting.
* New analytics key and backend endpoint for project service‑health; API
schemas added.
* Backend support for an additional log‑drain type (hidden from the UI).
* **Bug Fixes**
* Improved refresh behavior for service‑health data.
* Clear "No requests in this period" fallback and correct charts when
totals are zero.
* **Tests**
* Added unit tests for service‑health data extraction and
transformation.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46100?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
178 lines
3.6 KiB
TypeScript
178 lines
3.6 KiB
TypeScript
export const analyticsKeys = {
|
|
// logs/reports endpoints
|
|
functionsCombinedStats: (
|
|
projectRef: string | undefined,
|
|
{
|
|
interval,
|
|
functionId,
|
|
}: {
|
|
functionId: string | undefined
|
|
interval: string | undefined
|
|
}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'functions-combined-stats',
|
|
{
|
|
interval,
|
|
functionId,
|
|
},
|
|
] as const,
|
|
functionsInvStats: (
|
|
projectRef: string | undefined,
|
|
{
|
|
interval,
|
|
functionId,
|
|
}: {
|
|
functionId: string | undefined
|
|
interval: string | undefined
|
|
}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'functions-inv-stats',
|
|
{
|
|
interval,
|
|
functionId,
|
|
},
|
|
] as const,
|
|
functionsReqStats: (
|
|
projectRef: string | undefined,
|
|
{
|
|
interval,
|
|
functionId,
|
|
}: {
|
|
functionId: string | undefined
|
|
interval: string | undefined
|
|
}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'functions-req-stats',
|
|
{
|
|
interval,
|
|
functionId,
|
|
},
|
|
] as const,
|
|
functionsResourceUsage: (
|
|
projectRef: string | undefined,
|
|
{
|
|
interval,
|
|
functionId,
|
|
}: {
|
|
functionId: string | undefined
|
|
interval: string | undefined
|
|
}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'functions-resource-usage',
|
|
{
|
|
interval,
|
|
functionId,
|
|
},
|
|
] as const,
|
|
|
|
orgDailyStats: (
|
|
orgSlug: string | undefined,
|
|
{
|
|
startDate,
|
|
endDate,
|
|
projectRef,
|
|
}: {
|
|
startDate?: string
|
|
endDate?: string
|
|
projectRef?: string
|
|
}
|
|
) =>
|
|
[
|
|
'organizations',
|
|
orgSlug,
|
|
'daily-stats',
|
|
{
|
|
startDate: isoDateStringToDate(startDate),
|
|
endDate: isoDateStringToDate(endDate),
|
|
projectRef,
|
|
},
|
|
] as const,
|
|
infraMonitoring: (
|
|
projectRef: string | undefined,
|
|
{
|
|
attribute,
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier,
|
|
}: {
|
|
attribute?: string
|
|
startDate?: string
|
|
endDate?: string
|
|
interval?: string
|
|
databaseIdentifier?: string
|
|
}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'infra-monitoring',
|
|
{ attribute, startDate, endDate, interval, databaseIdentifier },
|
|
] as const,
|
|
infraMonitoringGroup: (
|
|
projectRef: string | undefined,
|
|
{
|
|
attributes,
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier,
|
|
}: {
|
|
attributes?: string[]
|
|
startDate?: string
|
|
endDate?: string
|
|
interval?: string
|
|
databaseIdentifier?: string
|
|
}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'infra-monitoring',
|
|
'group',
|
|
{
|
|
attributes: attributes ? [...attributes].sort() : undefined,
|
|
startDate,
|
|
endDate,
|
|
interval,
|
|
databaseIdentifier,
|
|
},
|
|
] as const,
|
|
usageApiCounts: (projectRef: string | undefined, interval: string | undefined) =>
|
|
['projects', projectRef, 'usage.api-counts', interval] as const,
|
|
|
|
usageApiRequestsCount: (projectRef: string | undefined) =>
|
|
['projects', projectRef, 'usage.api-requests-count'] as const,
|
|
|
|
serviceHealth: (
|
|
projectRef: string | undefined,
|
|
{
|
|
startDate,
|
|
endDate,
|
|
granularity,
|
|
}: {
|
|
startDate?: string
|
|
endDate?: string
|
|
granularity?: string
|
|
}
|
|
) => ['projects', projectRef, 'service-health', { startDate, endDate, granularity }] as const,
|
|
}
|
|
|
|
function isoDateStringToDate(isoDateString: string | undefined): string | undefined {
|
|
if (!isoDateString) return isoDateString
|
|
|
|
return isoDateString.split('T')[0]
|
|
}
|