diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.tsx index 7afc1c8034..55bc831e00 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricCard/MetricCard.tsx @@ -21,14 +21,14 @@ interface MetricCardProps { export function MetricCard({active, progress, label, status, resourcesUsed}: MetricCardProps) { const renderContent = () => { + if (progress === undefined && resourcesUsed === undefined) { + return
{i18n('no-data')}
; + } + return (
{progress &&
{formatUsage(progress)}
} - {resourcesUsed ? ( -
{resourcesUsed}
- ) : ( - i18n('no-data') - )} + {resourcesUsed &&
{resourcesUsed}
}
); }; diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx index a26663afbf..d8300900b1 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx @@ -53,7 +53,7 @@ export function MetricsCards({ }: MetricsCardsProps) { const location = useLocation(); - const {memoryUsed, memoryLimit, cpuUsed, cpuUsage, storageUsed, storageLimit} = metrics || {}; + const {memoryUsed, memoryLimit, cpuUsage, storageUsed, storageLimit} = metrics || {}; const {metricsTab} = useTypedSelector((state) => state.tenant); @@ -64,8 +64,7 @@ export function MetricsCards({ const storageStatus = storageUsageToStatus(storageUsage); const memoryStatus = memoryUsageToStatus(memoryUsage); - const {cpu, storage, memory} = formatTenantMetrics({ - cpu: cpuUsed, + const {storage, memory} = formatTenantMetrics({ storage: storageUsed, memory: memoryUsed, }); @@ -107,7 +106,6 @@ export function MetricsCards({ label="CPU" progress={cpuUsage} status={cpuStatus} - resourcesUsed={cpu} active={metricsTab === TENANT_METRICS_TABS_IDS.cpu} /> diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json b/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json index e750bb303e..35da7968e2 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +++ b/src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json @@ -23,7 +23,7 @@ "charts.queries-per-second": "Queries per second", "charts.transaction-latency": "Transactions latencies {{percentile}}", - "charts.cpu-usage": "CPU usage", + "charts.cpu-usage": "CPU cores used", "charts.storage-usage": "Tablet storage usage", "charts.memory-usage": "Memory usage", diff --git a/src/store/reducers/tenants/utils.ts b/src/store/reducers/tenants/utils.ts index 4019dd026e..e97e71f022 100644 --- a/src/store/reducers/tenants/utils.ts +++ b/src/store/reducers/tenants/utils.ts @@ -1,3 +1,4 @@ +import type {TPoolStats} from '../../../types/api/nodes'; import type {TTenant} from '../../../types/api/tenant'; import {formatBytes} from '../../../utils/bytesParsers'; import {formatCPUWithLabel} from '../../../utils/dataFormatters/dataFormatters'; @@ -21,6 +22,20 @@ const getTenantBackend = (tenant: TTenant) => { return node.Host ? `${node.Host}${address ? address : ''}` : undefined; }; +const calculateCpuUsage = (poolsStats: TPoolStats[] | undefined) => { + if (!poolsStats) { + return undefined; + } + + const systemPoolUsage = poolsStats?.find(({Name}) => Name === 'System')?.Usage || 0; + const userPoolUsage = poolsStats?.find(({Name}) => Name === 'User')?.Usage || 0; + const icPoolUsage = poolsStats?.find(({Name}) => Name === 'IC')?.Usage || 0; + + // We use max of system, user and ic pools usage to calculate cpu usage because + // only these pools directly indicate resources available to perform user queries + return Math.max(Number(systemPoolUsage), Number(userPoolUsage), Number(icPoolUsage)) * 100; +}; + export const calculateTenantMetrics = (tenant?: TTenant) => { const { CoresUsed, @@ -33,20 +48,13 @@ export const calculateTenantMetrics = (tenant?: TTenant) => { DatabaseQuotas = {}, } = tenant || {}; - const systemPoolUsage = PoolStats?.find(({Name}) => Name === 'System')?.Usage; - const userPoolUsage = PoolStats?.find(({Name}) => Name === 'User')?.Usage; - const cpu = isNumeric(CoresUsed) ? Number(CoresUsed) * 1_000_000 : undefined; const memory = isNumeric(MemoryUsed) ? Number(MemoryUsed) : undefined; const blobStorage = isNumeric(StorageAllocatedSize) ? Number(StorageAllocatedSize) : undefined; const tabletStorage = isNumeric(Metrics.Storage) ? Number(Metrics.Storage) : undefined; - // We use system pool usage and user pool usage to calculate cpu usage because - // only these pools directly indicate resources available to perform user queries - const cpuUsage = - isNumeric(systemPoolUsage) || isNumeric(userPoolUsage) - ? Math.max(Number(systemPoolUsage), Number(userPoolUsage)) * 100 - : undefined; + const cpuUsage = calculateCpuUsage(PoolStats); + const memoryLimit = isNumeric(MemoryLimit) ? Number(MemoryLimit) : undefined; const blobStorageLimit = isNumeric(StorageAllocatedLimit) ? Number(StorageAllocatedLimit) diff --git a/src/types/api/nodes.ts b/src/types/api/nodes.ts index 15b677d4cb..7f9517303c 100644 --- a/src/types/api/nodes.ts +++ b/src/types/api/nodes.ts @@ -81,8 +81,10 @@ export interface TSystemStateInfo { TotalSessions?: number; } +export type PoolName = 'System' | 'User' | 'Batch' | 'IO' | 'IC'; + export interface TPoolStats { - Name?: string; + Name?: PoolName; /** double */ Usage?: number; Threads?: number;