diff --git a/apps/studio/data/reports/database-charts.ts b/apps/studio/data/reports/database-charts.ts index 3f8efcc622c..692edba8947 100644 --- a/apps/studio/data/reports/database-charts.ts +++ b/apps/studio/data/reports/database-charts.ts @@ -7,210 +7,6 @@ import { DiskAttributesData } from '../config/disk-attributes-query' import { MaxConnectionsData } from '../database/max-connections-query' import { Project } from '../projects/project-detail-query' -export const getReportAttributes = (diskConfig?: DiskAttributesData): ReportAttributes[] => { - return [ - { - id: 'ram-usage', - label: 'Memory usage', - availableIn: ['free', 'pro'], - hide: false, - showTooltip: false, - showLegend: false, - hideChartType: false, - defaultChartStyle: 'bar', - showMaxValue: false, - showGrid: false, - syncId: 'database-reports', - valuePrecision: 0, - format: '%', - attributes: [ - { - attribute: 'ram_usage', - provider: 'infra-monitoring', - label: 'Memory usage', - format: '%', - tooltip: 'RAM usage by the database', - }, - ], - }, - { - id: 'avg_cpu_usage', - label: 'Average CPU usage', - syncId: 'database-reports', - format: '%', - valuePrecision: 2, - availableIn: ['free', 'pro'], - hide: false, - showTooltip: false, - showLegend: false, - showMaxValue: false, - showGrid: false, - hideChartType: false, - defaultChartStyle: 'bar', - attributes: [ - { - attribute: 'avg_cpu_usage', - provider: 'infra-monitoring', - label: 'Average CPU usage', - format: '%', - tooltip: 'Average CPU usage', - }, - ], - }, - { - id: 'max_cpu_usage', - label: 'Max CPU usage', - syncId: 'database-reports', - format: '%', - valuePrecision: 2, - availableIn: ['free', 'pro'], - hide: false, - showTooltip: false, - showLegend: false, - showMaxValue: false, - showGrid: false, - hideChartType: false, - defaultChartStyle: 'bar', - attributes: [ - { - attribute: 'max_cpu_usage', - provider: 'infra-monitoring', - label: 'Max CPU usage', - format: '%', - tooltip: 'Max CPU usage', - }, - ], - }, - { - id: 'disk-iops', - label: 'Disk Input/Output operations per second (IOPS)', - syncId: 'database-reports', - availableIn: ['free', 'pro'], - hide: false, - showTooltip: true, - valuePrecision: 2, - showLegend: true, - hideChartType: false, - showGrid: true, - showMaxValue: false, - YAxisProps: { - width: 35, - tickFormatter: (value: any) => numberFormatter(value, 2), - }, - defaultChartStyle: 'line', - docsUrl: `${DOCS_URL}/guides/platform/compute-and-disk#compute-size`, - 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: diskConfig?.attributes?.iops, - tooltip: - 'Maximum IOPS (Input/Output Operations Per Second) for your current compute size', - isMaxValue: true, - }, - ], - }, - { - id: 'disk-io-usage', - label: 'Disk IO Usage', - syncId: 'database-reports', - availableIn: ['team', 'enterprise'], - hide: false, - format: '%', - attributes: [], - }, - { - id: 'pooler-database-connections', - label: 'Pooler to Database connections', - syncId: 'database-reports', - valuePrecision: 0, - availableIn: ['free', 'pro'], - hide: false, - showTooltip: false, - showLegend: false, - showMaxValue: false, - hideChartType: false, - showGrid: false, - defaultChartStyle: 'bar', - attributes: [ - { - attribute: 'pg_stat_database_num_backends', - provider: 'infra-monitoring', - label: 'Database connections', - tooltip: 'Number of pooler connections to the database', - }, - ], - }, - { - id: 'supavisor-connections', - label: 'Shared Pooler connections', - syncId: 'database-reports', - valuePrecision: 0, - availableIn: ['free', 'pro'], - hide: false, - showTooltip: false, - showLegend: false, - showMaxValue: false, - showGrid: false, - hideChartType: false, - defaultChartStyle: 'bar', - attributes: [ - { - attribute: 'supavisor_connections_active', - provider: 'infra-monitoring', - label: 'Client to Shared Pooler connections', - tooltip: 'Active connections from clients to the shared pooler', - }, - ], - }, - { - id: 'pgbouncer-connections', - label: 'Dedicated Pooler connections', - syncId: 'database-reports', - valuePrecision: 0, - availableIn: ['pro', 'team'], - hide: false, - showTooltip: false, - showLegend: false, - showMaxValue: false, - showGrid: false, - hideChartType: false, - defaultChartStyle: 'bar', - attributes: [ - { - attribute: 'client_connections_pgbouncer', - provider: 'infra-monitoring', - label: 'Client to Dedicated Pooler connections', - tooltip: 'PgBouncer connections', - }, - ], - }, - { - id: 'disk-size', - label: 'Disk Usage', - syncId: 'database-reports', - availableIn: ['team', 'enterprise'], - hide: false, - attributes: [], - }, - ] -} - export const getReportAttributesV2: ( org: Organization, project: Project, @@ -227,7 +23,7 @@ export const getReportAttributesV2: ( id: 'ram-usage', label: 'Memory usage', docsUrl: `${DOCS_URL}/guides/telemetry/reports#memory-usage`, - availableIn: ['team', 'enterprise'], + availableIn: ['free', 'pro', 'team', 'enterprise'], hide: false, showTooltip: true, showLegend: true, @@ -272,7 +68,7 @@ export const getReportAttributesV2: ( syncId: 'database-reports', format: '%', valuePrecision: 2, - availableIn: ['team', 'enterprise'], + availableIn: ['free', 'pro', 'team', 'enterprise'], hide: false, showTooltip: true, showLegend: true, @@ -339,7 +135,7 @@ export const getReportAttributesV2: ( label: 'Disk Input/Output operations per second (IOPS)', docsUrl: `${DOCS_URL}/guides/telemetry/reports#disk-inputoutput-operations-per-second-iops`, syncId: 'database-reports', - availableIn: ['team', 'enterprise'], + availableIn: ['free', 'pro', 'team', 'enterprise'], hide: false, showTooltip: true, valuePrecision: 2, @@ -408,12 +204,46 @@ export const getReportAttributesV2: ( ], }, { + // Client Connections metric for free tier + id: 'client-connections-basic', + label: 'Database Connections', + syncId: 'database-reports', + valuePrecision: 0, + availableIn: ['free'], + hide: !isFreePlan, + showTooltip: false, + showLegend: false, + showMaxValue: true, + hideChartType: false, + showGrid: true, + YAxisProps: { width: 30 }, + defaultChartStyle: 'line', + docsUrl: `${DOCS_URL}/guides/telemetry/reports#database-connections`, + attributes: [ + { + attribute: 'total_db_connections', + 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, - availableIn: ['team', 'enterprise'], - hide: false, + availableIn: ['pro', 'team', 'enterprise'], + hide: isFreePlan, showTooltip: true, showLegend: true, showMaxValue: true, @@ -476,7 +306,7 @@ export const getReportAttributesV2: ( label: 'Dedicated Pooler Client Connections', syncId: 'database-reports', valuePrecision: 0, - availableIn: ['pro', 'team'], + availableIn: ['pro', 'team', 'enterprise'], hide: isFreePlan, showTooltip: true, showLegend: true, @@ -508,7 +338,7 @@ export const getReportAttributesV2: ( label: 'Shared Pooler (Supavisor) client connections', syncId: 'database-reports', valuePrecision: 0, - availableIn: ['pro', 'team'], + availableIn: ['pro', 'team', 'enterprise'], hide: isFreePlan, showTooltip: false, showLegend: false, @@ -531,7 +361,7 @@ export const getReportAttributesV2: ( label: 'Disk Usage', syncId: 'database-reports', valuePrecision: 2, - availableIn: ['free', 'pro', 'team'], + availableIn: ['free', 'pro', 'team', 'enterprise'], hide: false, showTooltip: true, showLegend: true, diff --git a/apps/studio/pages/project/[ref]/reports/database.tsx b/apps/studio/pages/project/[ref]/reports/database.tsx index 0ba53523e2e..5eaca8b089d 100644 --- a/apps/studio/pages/project/[ref]/reports/database.tsx +++ b/apps/studio/pages/project/[ref]/reports/database.tsx @@ -6,7 +6,7 @@ import Link from 'next/link' import { useEffect, useState } from 'react' import { toast } from 'sonner' -import { useFlag, useParams } from 'common' +import { useParams } from 'common' import ReportHeader from 'components/interfaces/Reports/ReportHeader' import ReportPadding from 'components/interfaces/Reports/ReportPadding' import { REPORT_DATERANGE_HELPER_LABELS } from 'components/interfaces/Reports/Reports.constants' @@ -33,7 +33,7 @@ import { useProjectDiskResizeMutation } from 'data/config/project-disk-resize-mu import { useDatabaseSizeQuery } from 'data/database/database-size-query' import { useMaxConnectionsQuery } from 'data/database/max-connections-query' import { usePgbouncerConfigQuery } from 'data/database/pgbouncer-config-query' -import { getReportAttributes, getReportAttributesV2 } from 'data/reports/database-charts' +import { getReportAttributesV2 } from 'data/reports/database-charts' import { useDatabaseReport } from 'data/reports/database-report-query' import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions' @@ -65,7 +65,6 @@ export default DatabaseReport const DatabaseUsage = () => { const { db, chart, ref } = useParams() - const isReportsV2 = useFlag('reportsDatabaseV2') const { data: project } = useSelectedProjectQuery() const { data: org } = useSelectedOrganizationQuery() @@ -81,10 +80,6 @@ const DatabaseUsage = () => { handleDatePickerChange, } = useReportDateRange(REPORT_DATERANGE_HELPER_LABELS.LAST_60_MINUTES) - const isTeamsOrEnterprisePlan = - !isOrgPlanLoading && (orgPlan?.id === 'team' || orgPlan?.id === 'enterprise') - const showChartsV2 = isReportsV2 || isTeamsOrEnterprisePlan - const state = useDatabaseSelectorStateSnapshot() const queryClient = useQueryClient() @@ -130,8 +125,7 @@ const DatabaseUsage = () => { } ) - const REPORT_ATTRIBUTES = getReportAttributes(diskConfig) - const REPORT_ATTRIBUTES_V2 = getReportAttributesV2( + const REPORT_ATTRIBUTES = getReportAttributesV2( org!, project!, diskConfig, @@ -149,51 +143,22 @@ const DatabaseUsage = () => { const onRefreshReport = async () => { if (!selectedDateRange) return - // [Joshen] Since we can't track individual loading states for each chart - // so for now we mock a loading state that only lasts for a second setIsRefreshing(true) refresh() const { period_start, period_end, interval } = selectedDateRange - REPORT_ATTRIBUTES.forEach((attr) => { - queryClient.invalidateQueries( - analyticsKeys.infraMonitoring(ref, { - attribute: attr?.id, - startDate: period_start.date, - endDate: period_end.date, - interval, - databaseIdentifier: state.selectedDatabaseId, - }) - ) + REPORT_ATTRIBUTES.forEach((chart: any) => { + chart.attributes.forEach((attr: any) => { + queryClient.invalidateQueries( + analyticsKeys.infraMonitoring(ref, { + attribute: attr.attribute, + startDate: period_start.date, + endDate: period_end.date, + interval, + databaseIdentifier: state.selectedDatabaseId, + }) + ) + }) }) - if (showChartsV2) { - REPORT_ATTRIBUTES_V2.forEach((chart: any) => { - chart.attributes.forEach((attr: any) => { - queryClient.invalidateQueries( - analyticsKeys.infraMonitoring(ref, { - attribute: attr.attribute, - startDate: period_start.date, - endDate: period_end.date, - interval, - databaseIdentifier: state.selectedDatabaseId, - }) - ) - }) - }) - } else { - REPORT_ATTRIBUTES.forEach((chart: any) => { - chart.attributes.forEach((attr: any) => { - queryClient.invalidateQueries( - analyticsKeys.infraMonitoring(ref, { - attribute: attr.attribute, - startDate: period_start.date, - endDate: period_end.date, - interval, - databaseIdentifier: state.selectedDatabaseId, - }) - ) - }) - }) - } if (isReplicaSelected) { queryClient.invalidateQueries( analyticsKeys.infraMonitoring(ref, { @@ -274,56 +239,37 @@ const DatabaseUsage = () => { > {selectedDateRange && orgPlan?.id && - (showChartsV2 - ? REPORT_ATTRIBUTES_V2.filter((chart) => !chart.hide).map((chart) => ( - - )) - : REPORT_ATTRIBUTES.filter((chart) => !chart.hide).map((chart, i) => - chart.availableIn?.includes(orgPlan?.id) ? ( - - ) : ( - - ) - ))} + REPORT_ATTRIBUTES.filter((chart) => !chart.hide).map((chart) => + chart.availableIn?.includes(orgPlan?.id) ? ( + + ) : ( + + ) + )} {selectedDateRange && isReplicaSelected && (