mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
## Problem Recent database report PRs introduced `(value: any)` type annotations in recharts `tickFormatter` callbacks, pushing the `@typescript-eslint/no-explicit-any` ESLint ratchet from baseline 1014 to 1017 and blocking all PR merges. ## Fix Replace `(value: any)` with `(value: number)` in all affected `tickFormatter` callbacks across the three flagged files. Recharts always passes a number to tick formatters, so this is a safe and accurate type. ## How to test - Run `pnpm lint --filter=studio` and confirm no new `@typescript-eslint/no-explicit-any` violations appear in the three changed files - Check the ESLint ratchet count is back at or below baseline 1014 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved type safety for Y‑axis tick formatters across observability charts (Memory, Swap, Network throughput, Disk IOPS/throughput/usage, Replication Lag), ensuring tick values are treated as numeric for more consistent chart rendering and reliability. [](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45794) <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Ali Waseem <waseema393@gmail.com>
542 lines
18 KiB
TypeScript
542 lines
18 KiB
TypeScript
import { COMPUTE_MAX_IOPS } from 'shared-data'
|
|
|
|
import { mapComputeSizeNameToAddonVariantId } from '@/components/interfaces/DiskManagement/DiskManagement.utils'
|
|
import { compactNumberFormatter } from '@/components/ui/Charts/Charts.utils'
|
|
import { ReportAttributes } from '@/components/ui/Charts/ComposedChart.utils'
|
|
import { DiskAttributesData } from '@/data/config/disk-attributes-query'
|
|
import { MaxConnectionsData } from '@/data/database/max-connections-query'
|
|
import { Project } from '@/data/projects/project-detail-query'
|
|
import { DOCS_URL } from '@/lib/constants'
|
|
import { formatBytes } from '@/lib/helpers'
|
|
|
|
export const getReportAttributesV2: (
|
|
entitledFeatures: string[],
|
|
project: Project,
|
|
diskConfig?: DiskAttributesData,
|
|
maxConnections?: MaxConnectionsData,
|
|
pgBouncerMaxConnections?: number,
|
|
isSpendCapEnabled?: boolean
|
|
) => ReportAttributes[] = (
|
|
entitledFeatures,
|
|
project,
|
|
diskConfig,
|
|
maxConnections,
|
|
pgBouncerMaxConnections,
|
|
isSpendCapEnabled
|
|
) => {
|
|
const provisionedDiskIops = diskConfig?.attributes?.iops
|
|
const computeIopsLimit =
|
|
COMPUTE_MAX_IOPS[mapComputeSizeNameToAddonVariantId(project?.infra_compute_size)]
|
|
const effectiveMaxIops =
|
|
typeof provisionedDiskIops === 'number' && typeof computeIopsLimit === 'number'
|
|
? Math.min(provisionedDiskIops, computeIopsLimit)
|
|
: provisionedDiskIops
|
|
|
|
return [
|
|
{
|
|
id: 'ram-usage',
|
|
label: 'Memory usage',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#memory-usage`,
|
|
hide: false,
|
|
showTooltip: true,
|
|
showLegend: true,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
showMaxValue: false,
|
|
showGrid: true,
|
|
syncId: 'database-reports',
|
|
valuePrecision: 2,
|
|
YAxisProps: {
|
|
width: 75,
|
|
tickFormatter: (value: number) => formatBytes(value, 2),
|
|
},
|
|
attributes: [
|
|
{
|
|
attribute: 'ram_usage_used',
|
|
provider: 'infra-monitoring',
|
|
label: 'Used',
|
|
tooltip:
|
|
'RAM in use by Postgres and the operating system. Sustained high usage may indicate memory pressure',
|
|
},
|
|
{
|
|
attribute: 'ram_usage_cache_and_buffers',
|
|
provider: 'infra-monitoring',
|
|
label: 'Cache + Buffers',
|
|
tooltip:
|
|
'RAM used by the operating system page cache and PostgreSQL buffers to accelerate disk reads/writes',
|
|
},
|
|
{
|
|
attribute: 'ram_usage_free',
|
|
provider: 'infra-monitoring',
|
|
label: 'Free',
|
|
tooltip:
|
|
'Unallocated memory available for use. A small portion is always reserved by the operating system',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'swap-usage',
|
|
label: 'Swap usage',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#memory-usage`,
|
|
hide: false,
|
|
showTooltip: true,
|
|
showLegend: false,
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
showMaxValue: false,
|
|
showGrid: true,
|
|
syncId: 'database-reports',
|
|
valuePrecision: 2,
|
|
YAxisProps: {
|
|
width: 75,
|
|
tickFormatter: (value: number) => formatBytes(value, 2),
|
|
},
|
|
attributes: [
|
|
{
|
|
attribute: 'swap_usage',
|
|
provider: 'infra-monitoring',
|
|
label: 'Swap',
|
|
tooltip:
|
|
'Swap space in use by the operating system. Sustained swap usage indicates memory pressure and may degrade database performance',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'cpu-usage',
|
|
label: 'CPU usage',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#cpu-usage`,
|
|
syncId: 'database-reports',
|
|
format: '%',
|
|
valuePrecision: 2,
|
|
hide: false,
|
|
showTooltip: true,
|
|
showLegend: true,
|
|
showMaxValue: false,
|
|
showGrid: true,
|
|
normalizeVisibleStackToPercent: true,
|
|
YAxisProps: {
|
|
width: 55,
|
|
domain: [0, 100] as [number, number],
|
|
allowDataOverflow: true,
|
|
tickFormatter: (v: number) => `${Math.round(v)}%`,
|
|
},
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
attributes: [
|
|
{
|
|
attribute: 'cpu_usage_busy_system',
|
|
provider: 'infra-monitoring',
|
|
label: 'System',
|
|
format: '%',
|
|
color: { light: '#EDC35E', dark: '#EDD35E' },
|
|
fill: { light: '#F6D99F', dark: '#5C5230' },
|
|
tooltip:
|
|
'CPU time spent on kernel operations (e.g., process scheduling, memory management). High values may indicate system overhead',
|
|
},
|
|
{
|
|
attribute: 'cpu_usage_busy_user',
|
|
provider: 'infra-monitoring',
|
|
label: 'User',
|
|
format: '%',
|
|
color: { light: '#0063E8', dark: '#65BCD9' },
|
|
fill: { light: '#80B1F4', dark: '#2A3D45' },
|
|
tooltip:
|
|
'CPU time used by database queries and user-space processes. High values may suggest CPU-intensive queries',
|
|
},
|
|
{
|
|
attribute: 'cpu_usage_busy_iowait',
|
|
provider: 'infra-monitoring',
|
|
label: 'IOwait',
|
|
format: '%',
|
|
color: { light: '#DB3A34', dark: '#FF6B6B' },
|
|
fill: { light: '#F2A7A3', dark: '#5C2A2A' },
|
|
tooltip:
|
|
'CPU time waiting for disk or network I/O. High values may indicate disk bottlenecks',
|
|
},
|
|
{
|
|
attribute: 'cpu_usage_busy_irqs',
|
|
provider: 'infra-monitoring',
|
|
label: 'IRQs',
|
|
format: '%',
|
|
color: { light: '#DA760B', dark: '#DA760B' },
|
|
fill: { light: '#FFB885', dark: '#5C3D0A' },
|
|
tooltip: 'CPU time handling hardware interrupt requests (IRQ)',
|
|
},
|
|
{
|
|
attribute: 'cpu_usage_busy_other',
|
|
provider: 'infra-monitoring',
|
|
label: 'Other',
|
|
format: '%',
|
|
color: { light: '#B616A6', dark: '#DB8DF9' },
|
|
fill: { light: '#DB8BD3', dark: '#4A3D5C' },
|
|
tooltip:
|
|
'CPU time spent on other tasks (e.g., background processes, software interrupts)',
|
|
},
|
|
{
|
|
attribute: 'cpu_usage_busy_idle',
|
|
provider: 'infra-monitoring',
|
|
label: 'Idle',
|
|
format: '%',
|
|
omitFromTotal: true,
|
|
color: { light: '#6EA85F', dark: '#A3FFC2' },
|
|
fill: { light: '#A6D8AE', dark: '#2A5C3F' },
|
|
tooltip: 'CPU time spent idle and available for new work',
|
|
},
|
|
{
|
|
attribute: 'cpu_usage_max',
|
|
provider: 'reference-line',
|
|
label: 'Max',
|
|
value: 100,
|
|
tooltip: 'Max CPU usage',
|
|
isMaxValue: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'network-throughput',
|
|
label: 'Network throughput',
|
|
syncId: 'database-reports',
|
|
hide: false,
|
|
showTooltip: true,
|
|
format: 'bytes-per-second',
|
|
valuePrecision: 1,
|
|
showLegend: true,
|
|
showMaxValue: false,
|
|
hideChartType: false,
|
|
showGrid: true,
|
|
YAxisProps: {
|
|
width: 70,
|
|
tickFormatter: (value: number) => `${formatBytes(value, 1)}/s`,
|
|
},
|
|
defaultChartStyle: 'stackedAreaLine',
|
|
attributes: [
|
|
{
|
|
attribute: 'network_receive_bytes',
|
|
provider: 'infra-monitoring',
|
|
label: 'Network in',
|
|
tooltip: 'Inbound network throughput (bytes per second)',
|
|
},
|
|
{
|
|
attribute: 'network_transmit_bytes',
|
|
provider: 'infra-monitoring',
|
|
label: 'Network out',
|
|
tooltip: 'Outbound network throughput (bytes per second)',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'disk-iops',
|
|
label: 'Disk Input/Output operations per second (IOPS)',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#disk-inputoutput-operations-per-second-iops`,
|
|
syncId: 'database-reports',
|
|
hide: false,
|
|
showTooltip: true,
|
|
valuePrecision: 0,
|
|
showLegend: true,
|
|
hideChartType: false,
|
|
showGrid: true,
|
|
showMaxValue: true,
|
|
YAxisProps: {
|
|
width: 55,
|
|
tickFormatter: (value: number) => compactNumberFormatter(value),
|
|
},
|
|
defaultChartStyle: 'bar',
|
|
attributes: [
|
|
{
|
|
attribute: 'disk_iops_write',
|
|
provider: 'infra-monitoring',
|
|
label: 'Write IOPS',
|
|
tooltip:
|
|
'Number of write operations per second. High values indicate frequent data writes, logging, or transaction activity',
|
|
},
|
|
{
|
|
attribute: 'disk_iops_read',
|
|
provider: 'infra-monitoring',
|
|
label: 'Read IOPS',
|
|
tooltip:
|
|
'Number of read operations per second. High values suggest frequent disk reads due to queries or poor caching',
|
|
},
|
|
{
|
|
attribute: 'disk_iops_max',
|
|
provider: 'reference-line',
|
|
label: 'Max IOPS',
|
|
value: effectiveMaxIops,
|
|
tooltip:
|
|
'Effective maximum IOPS for your current compute and disk configuration. Equal to the lower of the compute IOPS limit and the provisioned disk IOPS',
|
|
isMaxValue: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'disk-throughput',
|
|
label: 'Disk throughput',
|
|
docsUrl: `${DOCS_URL}/guides/platform/compute-add-ons#disk-throughput`,
|
|
syncId: 'database-reports',
|
|
hide: false,
|
|
showTooltip: true,
|
|
format: 'bytes-per-second',
|
|
valuePrecision: 1,
|
|
showLegend: true,
|
|
showMaxValue: true,
|
|
hideChartType: false,
|
|
showGrid: true,
|
|
YAxisProps: {
|
|
width: 70,
|
|
tickFormatter: (value: number) => `${formatBytes(value, 1)}/s`,
|
|
},
|
|
defaultChartStyle: 'stackedAreaLine',
|
|
attributes: [
|
|
{
|
|
attribute: 'disk_bytes_read',
|
|
provider: 'infra-monitoring',
|
|
label: 'Read throughput',
|
|
tooltip: 'Disk read throughput (bytes per second)',
|
|
},
|
|
{
|
|
attribute: 'disk_bytes_written',
|
|
provider: 'infra-monitoring',
|
|
label: 'Write throughput',
|
|
tooltip: 'Disk write throughput (bytes per second)',
|
|
},
|
|
{
|
|
attribute: 'disk_throughput_max',
|
|
provider: 'reference-line',
|
|
label: 'Max throughput',
|
|
value:
|
|
diskConfig?.attributes?.type === 'gp3' &&
|
|
typeof diskConfig.attributes.throughput_mbps === 'number'
|
|
? diskConfig.attributes.throughput_mbps * 1024 * 1024
|
|
: undefined,
|
|
tooltip: 'Maximum disk throughput for your current compute size',
|
|
isMaxValue: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// Client Connections metric for free tier
|
|
id: 'client-connections-basic',
|
|
label: 'Database Connections',
|
|
syncId: 'database-reports',
|
|
valuePrecision: 0,
|
|
hide: entitledFeatures.includes('database'),
|
|
showTooltip: false,
|
|
showLegend: false,
|
|
showMaxValue: true,
|
|
hideChartType: false,
|
|
showGrid: true,
|
|
YAxisProps: { width: 30 },
|
|
defaultChartStyle: 'bar',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#database-connections`,
|
|
attributes: [
|
|
{
|
|
attribute: 'pg_stat_database_num_backends',
|
|
provider: 'infra-monitoring',
|
|
label: 'Total connections',
|
|
tooltip: 'Total number of active database connections',
|
|
},
|
|
{
|
|
attribute: 'max_db_connections',
|
|
provider: 'reference-line',
|
|
label: 'Max connections',
|
|
value: maxConnections?.maxConnections,
|
|
tooltip: 'Max available connections for your current compute size',
|
|
isMaxValue: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
// advanced client connections metric for paid and above
|
|
id: 'client-connections',
|
|
label: 'Database Connections',
|
|
syncId: 'database-reports',
|
|
valuePrecision: 0,
|
|
entitlement: 'database',
|
|
requiredPlan: 'Pro',
|
|
hide: !entitledFeatures.includes('database'),
|
|
showTooltip: true,
|
|
showLegend: true,
|
|
showMaxValue: true,
|
|
hideChartType: false,
|
|
showGrid: true,
|
|
YAxisProps: { width: 30 },
|
|
defaultChartStyle: 'bar',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#database-connections`,
|
|
attributes: [
|
|
{
|
|
attribute: 'client_connections_postgres',
|
|
provider: 'infra-monitoring',
|
|
label: 'Postgres',
|
|
tooltip:
|
|
'Direct connections to the Postgres database from your application and external clients',
|
|
},
|
|
{
|
|
attribute: 'client_connections_authenticator',
|
|
provider: 'infra-monitoring',
|
|
label: 'PostgREST',
|
|
tooltip: 'Connection pool managed by PostgREST',
|
|
},
|
|
{
|
|
attribute: 'client_connections_supabase_admin',
|
|
provider: 'infra-monitoring',
|
|
label: 'Reserved',
|
|
tooltip:
|
|
'Administrative connections used by various Supabase services for internal operations and maintenance tasks',
|
|
},
|
|
{
|
|
attribute: 'client_connections_supabase_auth_admin',
|
|
provider: 'infra-monitoring',
|
|
label: 'Auth',
|
|
tooltip: 'Connection pool managed by Supabase Auth',
|
|
},
|
|
{
|
|
attribute: 'client_connections_supabase_storage_admin',
|
|
provider: 'infra-monitoring',
|
|
label: 'Storage',
|
|
tooltip: 'Connection pool managed by Supabase Storage',
|
|
},
|
|
{
|
|
attribute: 'client_connections_other',
|
|
provider: 'infra-monitoring',
|
|
label: 'Other roles',
|
|
tooltip: "Miscellaneous database connections that don't fall into other categories.",
|
|
},
|
|
{
|
|
attribute: 'max_db_connections',
|
|
provider: 'reference-line',
|
|
label: 'Max connections',
|
|
value: maxConnections?.maxConnections,
|
|
tooltip: 'Max available connections for your current compute size',
|
|
isMaxValue: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'pgbouncer-connections',
|
|
label: 'Dedicated Pooler Client Connections',
|
|
syncId: 'database-reports',
|
|
valuePrecision: 0,
|
|
entitlement: 'database',
|
|
requiredPlan: 'Pro',
|
|
hide: !entitledFeatures.includes('database'),
|
|
showTooltip: true,
|
|
showLegend: true,
|
|
showMaxValue: true,
|
|
showGrid: true,
|
|
YAxisProps: { width: 30 },
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
docsUrl: `${DOCS_URL}/guides/platform/compute-and-disk#limits-and-constraints`,
|
|
attributes: [
|
|
{
|
|
attribute: 'client_connections_pgbouncer',
|
|
provider: 'infra-monitoring',
|
|
label: 'pgbouncer',
|
|
tooltip: 'PgBouncer connections',
|
|
},
|
|
{
|
|
attribute: 'pg_pooler_max_connections',
|
|
provider: 'reference-line',
|
|
label: 'Max pooler connections',
|
|
value: pgBouncerMaxConnections,
|
|
tooltip: 'Maximum allowed pooler connections for your current compute size',
|
|
isMaxValue: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'supavisor-connections-active',
|
|
label: 'Shared Pooler (Supavisor) client connections',
|
|
syncId: 'database-reports',
|
|
valuePrecision: 0,
|
|
entitlement: 'database',
|
|
requiredPlan: 'Pro',
|
|
hide: !entitledFeatures.includes('database'),
|
|
showTooltip: false,
|
|
showLegend: false,
|
|
showMaxValue: false,
|
|
showGrid: true,
|
|
YAxisProps: { width: 30 },
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
attributes: [
|
|
{
|
|
attribute: 'supavisor_connections_active',
|
|
provider: 'infra-monitoring',
|
|
label: 'supavisor',
|
|
tooltip: 'Supavisor connections',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'disk-size',
|
|
label: 'Disk Usage',
|
|
syncId: 'database-reports',
|
|
valuePrecision: 2,
|
|
hide: false,
|
|
showTooltip: true,
|
|
showLegend: true,
|
|
showMaxValue: true,
|
|
showGrid: true,
|
|
YAxisProps: {
|
|
width: 65,
|
|
tickFormatter: (value: number) => formatBytes(value, 1),
|
|
},
|
|
hideChartType: false,
|
|
defaultChartStyle: 'bar',
|
|
docsUrl: `${DOCS_URL}/guides/telemetry/reports#disk-size`,
|
|
attributes: [
|
|
{
|
|
attribute: 'disk_fs_used_system',
|
|
provider: 'infra-monitoring',
|
|
format: 'bytes',
|
|
label: 'System',
|
|
tooltip: 'Reserved space for the system to ensure your database runs smoothly',
|
|
},
|
|
{
|
|
attribute: 'disk_fs_used_wal',
|
|
provider: 'infra-monitoring',
|
|
format: 'bytes',
|
|
label: 'WAL',
|
|
tooltip:
|
|
'Disk usage by the write-ahead log. The usage depends on your WAL settings and the amount of data being written to the database',
|
|
},
|
|
{
|
|
attribute: 'pg_database_size',
|
|
provider: 'infra-monitoring',
|
|
format: 'bytes',
|
|
label: 'Database',
|
|
tooltip: 'Disk usage by your database (tables, indexes, data, ...)',
|
|
},
|
|
{
|
|
attribute: 'disk_fs_size',
|
|
provider: 'infra-monitoring',
|
|
isMaxValue: true,
|
|
format: 'bytes',
|
|
label: 'Disk Size',
|
|
tooltip: 'Disk Size refers to the total space your project occupies on disk',
|
|
},
|
|
entitledFeatures.includes('database') &&
|
|
(isSpendCapEnabled
|
|
? {
|
|
attribute: 'pg_database_size_percent_paid_spendCap',
|
|
provider: 'reference-line',
|
|
isReferenceLine: true,
|
|
strokeDasharray: '4 2',
|
|
label: 'Spend cap enabled',
|
|
value: diskConfig?.attributes?.size_gb! * 1024 * 1024 * 1024,
|
|
className: '[&_line]:stroke-yellow-800! [&_line]:opacity-100!',
|
|
opacity: 1,
|
|
}
|
|
: {
|
|
attribute: 'pg_database_size_percent_paid',
|
|
provider: 'reference-line',
|
|
isReferenceLine: true,
|
|
label: '90% - Disk resize threshold',
|
|
className: '[&_line]:stroke-yellow-800!',
|
|
value: diskConfig?.attributes?.size_gb! * 1024 * 1024 * 1024 * 0.9,
|
|
}),
|
|
],
|
|
},
|
|
]
|
|
}
|