From 37ee90d452851e475564f8111d51a72ee5bfb84f Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Sat, 2 Nov 2024 15:02:54 +0300 Subject: [PATCH 01/14] feat: prototype --- src/components/MemoryViewer/MemoryViewer.scss | 195 ++++++++++++++++ src/components/MemoryViewer/MemoryViewer.tsx | 218 ++++++++++++++++++ src/components/MemoryViewer/i18n/en.json | 9 + src/components/MemoryViewer/i18n/index.ts | 7 + .../ProgressViewer/ProgressViewer.tsx | 2 + src/components/nodesColumns/columns.tsx | 37 ++- src/components/nodesColumns/constants.ts | 2 +- src/components/nodesColumns/i18n/en.json | 1 + .../TenantMemory/TopNodesByMemory.tsx | 11 +- src/types/api/nodes.ts | 20 ++ 10 files changed, 491 insertions(+), 11 deletions(-) create mode 100644 src/components/MemoryViewer/MemoryViewer.scss create mode 100644 src/components/MemoryViewer/MemoryViewer.tsx create mode 100644 src/components/MemoryViewer/i18n/en.json create mode 100644 src/components/MemoryViewer/i18n/index.ts diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss new file mode 100644 index 000000000..cdca73b89 --- /dev/null +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -0,0 +1,195 @@ +@import '../../styles/mixins.scss'; + +.memory-viewer { + $block: &; + + position: relative; + z-index: 0; + min-width: 150px; + padding: 0 4px; + + &__progress-container { + position: relative; + height: 23px; + border-radius: 2px; + background: var(--g-color-base-generic); + overflow: hidden; + } + + &__container { + display: flex; + align-items: end; + text-align: end; + } + + &__legend { + width: 20px; + height: 20px; + + margin-right: 4px; + + &_type_ExternalConsumption { + background-color: var(--g-color-base-info-medium); + } + + &_type_AllocatorCachesMemory { + background-color: var(--g-color-base-warning-medium); + } + + &_type_SharedCacheConsumption { + background-color: var(--g-color-base-utility-medium); + } + + &_type_MemTableConsumption { + background-color: var(--g-color-base-danger-medium); + } + + &_type_QueryExecutionConsumption { + background-color: var(--g-color-base-misc-medium); + } + } + + &__segment { + position: absolute; + height: 100%; + + &_type_ExternalConsumption { + background-color: var(--g-color-base-info-medium); + } + + &_type_AllocatorCachesMemory { + background-color: var(--g-color-base-warning-medium); + } + + &_type_SharedCacheConsumption { + background-color: var(--g-color-base-utility-medium); + } + + &_type_MemTableConsumption { + background-color: var(--g-color-base-danger-medium); + } + + &_type_QueryExecutionConsumption { + background-color: var(--g-color-base-misc-medium); + } + } + + &__legend { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 8px; + color: var(--g-color-text-complementary); + } + + &__legend-item { + display: flex; + align-items: center; + gap: 4px; + white-space: nowrap; + } + + &__legend-color { + width: 12px; + height: 12px; + border-radius: 2px; + flex-shrink: 0; + } + + &_theme_dark { + color: var(--g-color-text-light-primary); + + #{$block}__segment { + opacity: 0.75; + } + } + + &_status { + &_good { + #{$block}__progress-container { + background-color: var(--g-color-base-positive-light); + } + } + &_warning { + #{$block}__progress-container { + background-color: var(--g-color-base-yellow-light); + } + } + &_danger { + #{$block}__progress-container { + background-color: var(--g-color-base-danger-light); + } + } + } + + &_size { + &_xs { + height: 20px; + @include body-2-typography(); + } + + &_s { + height: 28px; + font-size: var(--g-text-body-1-font-size); + line-height: 28px; + } + + &_m { + height: 32px; + font-size: var(--g-text-body-2-font-size); + line-height: 32px; + } + + &_ns { + height: 24px; + font-size: 13px; + line-height: var(--g-text-subheader-3-line-height); + } + + &_n { + height: 36px; + font-size: var(--g-text-body-1-font-size); + line-height: 36px; + } + + &_l { + height: 38px; + font-size: var(--g-text-subheader-3-font-size); + line-height: 38px; + } + + &_head { + font-size: var(--g-text-body-1-font-size); + line-height: 36px; + } + + #{$block}__progress-container { + height: inherit; + } + } + + &__text { + display: flex; + align-items: center; + justify-content: center; + } + + &__memory-segment { + display: flex; + align-items: center; + + width: 280px; + } + + &__hard-limit { + position: absolute; + height: 100%; + background-color: var(--g-color-base-danger-medium); + } + + &__soft-limit { + position: absolute; + height: 100%; + background-color: var(--g-color-base-warning-medium); + } +} diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx new file mode 100644 index 000000000..ec971cf5e --- /dev/null +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -0,0 +1,218 @@ +import React from 'react'; + +import {DefinitionList, useTheme} from '@gravity-ui/uikit'; + +import type {TMemoryStats} from '../../types/api/nodes'; +import {cn} from '../../utils/cn'; +import {formatNumber, roundToPrecision} from '../../utils/dataFormatters/dataFormatters'; +import {calculateProgressStatus} from '../../utils/progress'; +import {UNBREAKABLE_GAP, isNumeric} from '../../utils/utils'; +import {HoverPopup} from '../HoverPopup/HoverPopup'; +import {ProgressViewer} from '../ProgressViewer/ProgressViewer'; + +import i18n from './i18n'; + +import './MemoryViewer.scss'; + +const b = cn('memory-viewer'); + +type FormatProgressViewerValues = ( + value?: number, + capacity?: number, +) => (string | number | undefined)[]; + +const formatValue2 = (value?: number) => { + return formatNumber(roundToPrecision(Number(value), 2)); +}; + +const defaultFormatValues: FormatProgressViewerValues = (value, total) => { + return [formatValue2(value), formatValue2(total)]; +}; + +type ProgressViewerSize = 'xs' | 's' | 'ns' | 'm' | 'n' | 'l' | 'head'; + +export interface MemoryProgressViewerProps { + stats?: TMemoryStats; + totalCapacity: number; + className?: string; + size?: ProgressViewerSize; + warningThreshold?: number; + value?: number | string; + capacity?: number | string; + formatValues?: FormatProgressViewerValues; + percents?: boolean; + dangerThreshold?: number; +} + +export function MemoryViewer({ + stats, + value, + capacity, + percents, + formatValues = defaultFormatValues, + totalCapacity, + className, + size = 'xs', + warningThreshold = 60, + dangerThreshold = 80, +}: MemoryProgressViewerProps) { + const theme = useTheme(); + + let fillWidth = + Math.round((parseFloat(String(value)) / parseFloat(String(capacity))) * 100) || 0; + fillWidth = fillWidth > 100 ? 100 : fillWidth; + let valueText: number | string | undefined = value, + capacityText: number | string | undefined = capacity, + divider = '/'; + if (percents) { + valueText = fillWidth + '%'; + capacityText = ''; + divider = ''; + } else if (formatValues) { + [valueText, capacityText] = formatValues(Number(value), Number(capacity)); + } + + const renderContent = () => { + if (isNumeric(capacity)) { + return `${valueText} ${divider} ${capacityText}`; + } + + return valueText; + }; + + const calculateMemoryPercentage = (value: number) => { + if (!value) { + return 0; + } + return parseFloat(((value / parseFloat(String(capacity))) * 100).toFixed(2)); + }; + + const memorySegments = [ + { + label: i18n('text_external-consumption'), + key: 'ExternalConsumption', + value: parseFloat(stats?.ExternalConsumption || '0'), + }, + { + label: i18n('text_allocator-caches'), + key: 'AllocatorCachesMemory', + value: parseFloat(stats?.AllocatorCachesMemory || '0'), + }, + { + label: i18n('text_shared-cache'), + key: 'SharedCacheConsumption', + value: parseFloat(stats?.SharedCacheConsumption || '0'), + capacity: stats?.SharedCacheLimit, + }, + { + label: i18n('text_memtable'), + key: 'MemTableConsumption', + value: parseFloat(stats?.MemTableConsumption || '0'), + capacity: stats?.MemTableLimit, + }, + { + label: i18n('text_query-execution'), + key: 'QueryExecutionConsumption', + value: parseFloat(stats?.QueryExecutionConsumption || '0'), + capacity: stats?.QueryExecutionLimit, + }, + ]; + + console.log(memorySegments); + + const totalUsedMemory = + memorySegments.reduce((acc, segment) => acc + calculateMemoryPercentage(segment.value), 0) / + totalCapacity; + + const status = calculateProgressStatus({ + fillWidth: totalUsedMemory, + warningThreshold, + dangerThreshold, + colorizeProgress: true, + }); + + let currentPosition = 0; + + return ( + + {memorySegments + .filter(({value}) => value) + .map(({label, value, capacity, key}) => ( + +
+
{label}
+ + } + > +
+ {capacity ? ( + + + {UNBREAKABLE_GAP} + + ) : null} +
+ {formatValues(value, value)[1]} +
+ {UNBREAKABLE_GAP + '/' + UNBREAKABLE_GAP} +
+ {calculateMemoryPercentage(value)}% total +
+
+
+ ))} + + } + > +
+
+ {memorySegments.map((segment) => { + const position = currentPosition; + currentPosition += calculateMemoryPercentage(segment.value); + + return ( +
+ ); + })} + {stats?.SoftLimit ? ( +
+ ) : null} + {stats?.HardLimit ? ( +
+ ) : null} +
{renderContent()}
+
+
+ + ); +} diff --git a/src/components/MemoryViewer/i18n/en.json b/src/components/MemoryViewer/i18n/en.json new file mode 100644 index 000000000..2e3cebe2f --- /dev/null +++ b/src/components/MemoryViewer/i18n/en.json @@ -0,0 +1,9 @@ +{ + "text_memory-detailed": "Memory Detailed", + "text_external-consumption": "External Consumption", + "text_allocator-caches": "Allocator Caches", + "text_shared-cache": "Shared Cache", + "text_memtable": "MemTable", + "text_query-execution": "Query Execution", + "memory-detailed": "Memory Detailed" +} diff --git a/src/components/MemoryViewer/i18n/index.ts b/src/components/MemoryViewer/i18n/index.ts new file mode 100644 index 000000000..831cd3ea1 --- /dev/null +++ b/src/components/MemoryViewer/i18n/index.ts @@ -0,0 +1,7 @@ +import {registerKeysets} from '../../../utils/i18n'; + +import en from './en.json'; + +const COMPONENT = 'ydb-memory-viewer'; + +export default registerKeysets(COMPONENT, {en}); diff --git a/src/components/ProgressViewer/ProgressViewer.tsx b/src/components/ProgressViewer/ProgressViewer.tsx index 2176de3ca..7273078be 100644 --- a/src/components/ProgressViewer/ProgressViewer.tsx +++ b/src/components/ProgressViewer/ProgressViewer.tsx @@ -95,6 +95,8 @@ export function ProgressViewer({ width: fillWidth + '%', }; + console.log(lineStyle); + const renderContent = () => { if (isNumeric(capacity) && !hideCapacity) { return `${valueText} ${divider} ${capacityText}`; diff --git a/src/components/nodesColumns/columns.tsx b/src/components/nodesColumns/columns.tsx index e5a09a780..081b7b193 100644 --- a/src/components/nodesColumns/columns.tsx +++ b/src/components/nodesColumns/columns.tsx @@ -2,7 +2,7 @@ import DataTable from '@gravity-ui/react-data-table'; import {DefinitionList} from '@gravity-ui/uikit'; import {getLoadSeverityForNode} from '../../store/reducers/nodes/utils'; -import type {TPoolStats} from '../../types/api/nodes'; +import type {TMemoryStats, TPoolStats} from '../../types/api/nodes'; import type {TTabletStateInfo} from '../../types/api/tablet'; import {valueIsDefined} from '../../utils'; import {cn} from '../../utils/cn'; @@ -15,6 +15,7 @@ import {getSpaceUsageSeverity} from '../../utils/storage'; import type {Column} from '../../utils/tableUtils/types'; import {isNumeric} from '../../utils/utils'; import {CellWithPopover} from '../CellWithPopover/CellWithPopover'; +import {MemoryViewer} from '../MemoryViewer/MemoryViewer'; import {NodeHostWrapper} from '../NodeHostWrapper/NodeHostWrapper'; import type {NodeHostData} from '../NodeHostWrapper/NodeHostWrapper'; import {PoolsGraph} from '../PoolsGraph/PoolsGraph'; @@ -193,6 +194,40 @@ export function getSharedCacheUsageColumn< resizeMinWidth: 170, }; } +export function getMemoryDetailedColumn< + T extends {MemoryStats?: TMemoryStats; MemoryUsed?: string; MemoryLimit?: string}, +>(): Column { + return { + name: NODES_COLUMNS_IDS.Memory, + header: NODES_COLUMNS_TITLES.Memory, + defaultOrder: DataTable.DESCENDING, + render: ({row}) => { + const totalCapacity = parseFloat(String(row.MemoryStats?.HardLimit)); + return ( + + ); + }, + align: DataTable.LEFT, + width: 500, + resizeMinWidth: 170, + }; +} export function getPoolsColumn(): Column { return { name: NODES_COLUMNS_IDS.Pools, diff --git a/src/components/nodesColumns/constants.ts b/src/components/nodesColumns/constants.ts index 887b3fa87..bc9ea2e11 100644 --- a/src/components/nodesColumns/constants.ts +++ b/src/components/nodesColumns/constants.ts @@ -111,7 +111,7 @@ export const NODES_COLUMNS_TO_DATA_FIELDS: Record[], NodesRequiredField[]] { - const memoryColumn = { - ...getMemoryColumn(), - header: i18n('column-header.process'), - }; - const columns = [ getNodeIdColumn(), getHostColumn(params), getUptimeColumn(), getLoadColumn(), - memoryColumn, - getSharedCacheUsageColumn(), + getMemoryDetailedColumn(), getSessionsColumn(), getTabletsColumn(params), ]; diff --git a/src/types/api/nodes.ts b/src/types/api/nodes.ts index 285b090b4..7809dc5e4 100644 --- a/src/types/api/nodes.ts +++ b/src/types/api/nodes.ts @@ -38,6 +38,23 @@ export interface TNodesGroup { NodeCount: number; } +export interface TMemoryStats { + ExternalConsumption?: string; + AllocatorCachesMemory?: string; + + SharedCacheConsumption?: string; + SharedCacheLimit?: string; + + MemTableConsumption?: string; + MemTableLimit?: string; + + QueryExecutionConsumption?: string; + QueryExecutionLimit?: string; + + HardLimit?: string; + SoftLimit?: string; +} + /** * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto */ @@ -80,6 +97,8 @@ export interface TSystemStateInfo { CoresUsed?: number; CoresTotal?: number; + MemoryStats?: TMemoryStats; + /** * int64 * @@ -175,6 +194,7 @@ export type NodesRequiredField = | 'Version' | 'Uptime' | 'Memory' + | 'MemoryDetailed' | 'CPU' | 'LoadAverage' | 'Missing' From 8ce353911bd49d68eaffee78284fd2642e9f7d63 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Fri, 8 Nov 2024 13:17:34 +0300 Subject: [PATCH 02/14] feat: better code --- src/components/MemoryViewer/MemoryViewer.scss | 76 ++------- src/components/MemoryViewer/MemoryViewer.tsx | 161 +++++------------- src/components/MemoryViewer/i18n/en.json | 2 + src/components/MemoryViewer/utils.ts | 62 +++++++ .../ProgressViewer/ProgressViewer.tsx | 2 - src/components/nodesColumns/columns.tsx | 48 ++---- .../TenantMemory/TopNodesByMemory.tsx | 4 +- src/types/api/nodes.ts | 1 + 8 files changed, 137 insertions(+), 219 deletions(-) create mode 100644 src/components/MemoryViewer/utils.ts diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss index cdca73b89..c5a61856b 100644 --- a/src/components/MemoryViewer/MemoryViewer.scss +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -5,27 +5,31 @@ position: relative; z-index: 0; + min-width: 150px; padding: 0 4px; &__progress-container { position: relative; + + overflow: hidden; + height: 23px; + border-radius: 2px; background: var(--g-color-base-generic); - overflow: hidden; } &__container { display: flex; align-items: end; + text-align: end; } &__legend { width: 20px; height: 20px; - margin-right: 4px; &_type_ExternalConsumption { @@ -51,6 +55,7 @@ &__segment { position: absolute; + height: 100%; &_type_ExternalConsumption { @@ -78,7 +83,9 @@ display: flex; flex-wrap: wrap; gap: 12px; + margin-top: 8px; + color: var(--g-color-text-complementary); } @@ -86,14 +93,17 @@ display: flex; align-items: center; gap: 4px; + white-space: nowrap; } &__legend-color { + flex-shrink: 0; + width: 12px; height: 12px; + border-radius: 2px; - flex-shrink: 0; } &_theme_dark { @@ -123,45 +133,8 @@ } &_size { - &_xs { - height: 20px; - @include body-2-typography(); - } - - &_s { - height: 28px; - font-size: var(--g-text-body-1-font-size); - line-height: 28px; - } - - &_m { - height: 32px; - font-size: var(--g-text-body-2-font-size); - line-height: 32px; - } - - &_ns { - height: 24px; - font-size: 13px; - line-height: var(--g-text-subheader-3-line-height); - } - - &_n { - height: 36px; - font-size: var(--g-text-body-1-font-size); - line-height: 36px; - } - - &_l { - height: 38px; - font-size: var(--g-text-subheader-3-font-size); - line-height: 38px; - } - - &_head { - font-size: var(--g-text-body-1-font-size); - line-height: 36px; - } + height: 20px; + @include body-2-typography(); #{$block}__progress-container { height: inherit; @@ -170,26 +143,7 @@ &__text { display: flex; - align-items: center; justify-content: center; - } - - &__memory-segment { - display: flex; align-items: center; - - width: 280px; - } - - &__hard-limit { - position: absolute; - height: 100%; - background-color: var(--g-color-base-danger-medium); - } - - &__soft-limit { - position: absolute; - height: 100%; - background-color: var(--g-color-base-warning-medium); } } diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index ec971cf5e..fbd673797 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -1,16 +1,13 @@ -import React from 'react'; - import {DefinitionList, useTheme} from '@gravity-ui/uikit'; import type {TMemoryStats} from '../../types/api/nodes'; import {cn} from '../../utils/cn'; -import {formatNumber, roundToPrecision} from '../../utils/dataFormatters/dataFormatters'; import {calculateProgressStatus} from '../../utils/progress'; -import {UNBREAKABLE_GAP, isNumeric} from '../../utils/utils'; +import {isNumeric} from '../../utils/utils'; import {HoverPopup} from '../HoverPopup/HoverPopup'; import {ProgressViewer} from '../ProgressViewer/ProgressViewer'; -import i18n from './i18n'; +import {getMemorySegments} from './utils'; import './MemoryViewer.scss'; @@ -21,25 +18,13 @@ type FormatProgressViewerValues = ( capacity?: number, ) => (string | number | undefined)[]; -const formatValue2 = (value?: number) => { - return formatNumber(roundToPrecision(Number(value), 2)); -}; - -const defaultFormatValues: FormatProgressViewerValues = (value, total) => { - return [formatValue2(value), formatValue2(total)]; -}; - -type ProgressViewerSize = 'xs' | 's' | 'ns' | 'm' | 'n' | 'l' | 'head'; - export interface MemoryProgressViewerProps { - stats?: TMemoryStats; - totalCapacity: number; + stats: TMemoryStats; className?: string; - size?: ProgressViewerSize; warningThreshold?: number; value?: number | string; capacity?: number | string; - formatValues?: FormatProgressViewerValues; + formatValues: FormatProgressViewerValues; percents?: boolean; dangerThreshold?: number; } @@ -49,10 +34,8 @@ export function MemoryViewer({ value, capacity, percents, - formatValues = defaultFormatValues, - totalCapacity, + formatValues, className, - size = 'xs', warningThreshold = 60, dangerThreshold = 80, }: MemoryProgressViewerProps) { @@ -80,49 +63,20 @@ export function MemoryViewer({ return valueText; }; - const calculateMemoryPercentage = (value: number) => { + const calculateMemoryShare = (segmentSize: number) => { if (!value) { return 0; } - return parseFloat(((value / parseFloat(String(capacity))) * 100).toFixed(2)); + return (segmentSize / parseFloat(String(capacity))) * 100; }; - const memorySegments = [ - { - label: i18n('text_external-consumption'), - key: 'ExternalConsumption', - value: parseFloat(stats?.ExternalConsumption || '0'), - }, - { - label: i18n('text_allocator-caches'), - key: 'AllocatorCachesMemory', - value: parseFloat(stats?.AllocatorCachesMemory || '0'), - }, - { - label: i18n('text_shared-cache'), - key: 'SharedCacheConsumption', - value: parseFloat(stats?.SharedCacheConsumption || '0'), - capacity: stats?.SharedCacheLimit, - }, - { - label: i18n('text_memtable'), - key: 'MemTableConsumption', - value: parseFloat(stats?.MemTableConsumption || '0'), - capacity: stats?.MemTableLimit, - }, - { - label: i18n('text_query-execution'), - key: 'QueryExecutionConsumption', - value: parseFloat(stats?.QueryExecutionConsumption || '0'), - capacity: stats?.QueryExecutionLimit, - }, - ]; - - console.log(memorySegments); + const memorySegments = getMemorySegments(stats); const totalUsedMemory = - memorySegments.reduce((acc, segment) => acc + calculateMemoryPercentage(segment.value), 0) / - totalCapacity; + memorySegments + .filter(({isInfo}) => !isInfo) + .reduce((acc, segment) => acc + calculateMemoryShare(segment.value), 0) / + parseFloat(String(capacity)); const status = calculateProgressStatus({ fillWidth: totalUsedMemory, @@ -137,9 +91,8 @@ export function MemoryViewer({ - {memorySegments - .filter(({value}) => value) - .map(({label, value, capacity, key}) => ( + {memorySegments.map( + ({label, value: segmentSize, capacity: segmentCapacity, key}) => ( } > -
- {capacity ? ( - - - {UNBREAKABLE_GAP} - - ) : null} -
- {formatValues(value, value)[1]} -
- {UNBREAKABLE_GAP + '/' + UNBREAKABLE_GAP} -
- {calculateMemoryPercentage(value)}% total -
-
+ {segmentCapacity ? ( + + ) : ( + formatValues(segmentSize)[0] + )}
- ))} + ), + )} } > -
+
- {memorySegments.map((segment) => { - const position = currentPosition; - currentPosition += calculateMemoryPercentage(segment.value); - - return ( -
- ); - })} - {stats?.SoftLimit ? ( -
- ) : null} - {stats?.HardLimit ? ( -
- ) : null} + {memorySegments + .filter(({isInfo}) => !isInfo) + .map((segment) => { + const position = currentPosition; + currentPosition += calculateMemoryShare(segment.value); + + return ( +
+ ); + })}
{renderContent()}
diff --git a/src/components/MemoryViewer/i18n/en.json b/src/components/MemoryViewer/i18n/en.json index 2e3cebe2f..6c743d7d5 100644 --- a/src/components/MemoryViewer/i18n/en.json +++ b/src/components/MemoryViewer/i18n/en.json @@ -5,5 +5,7 @@ "text_shared-cache": "Shared Cache", "text_memtable": "MemTable", "text_query-execution": "Query Execution", + "text_soft-limit": "Soft Limit", + "text_hard-limit": "Hard Limit", "memory-detailed": "Memory Detailed" } diff --git a/src/components/MemoryViewer/utils.ts b/src/components/MemoryViewer/utils.ts new file mode 100644 index 000000000..dd3e715e4 --- /dev/null +++ b/src/components/MemoryViewer/utils.ts @@ -0,0 +1,62 @@ +import type {TMemoryStats} from '../../types/api/nodes'; +import {isNumeric} from '../../utils/utils'; + +import i18n from './i18n'; + +function getMaybeNumber(value: string | number | undefined): number | undefined { + return isNumeric(value) ? parseFloat(String(value)) : undefined; +} + +interface MemorySegment { + label: string; + key: string; + value: number; + capacity?: number; + isInfo?: boolean; +} + +export function getMemorySegments(stats: TMemoryStats): MemorySegment[] { + const segments = [ + { + label: i18n('text_external-consumption'), + key: 'ExternalConsumption', + value: getMaybeNumber(stats.ExternalConsumption), + isInfo: true, + }, + { + label: i18n('text_allocator-caches'), + key: 'AllocatorCachesMemory', + value: getMaybeNumber(stats.AllocatorCachesMemory), + }, + { + label: i18n('text_shared-cache'), + key: 'SharedCacheConsumption', + value: getMaybeNumber(stats.SharedCacheConsumption), + capacity: getMaybeNumber(stats.SharedCacheLimit), + }, + { + label: i18n('text_memtable'), + key: 'MemTableConsumption', + value: getMaybeNumber(stats.MemTableConsumption), + capacity: getMaybeNumber(stats.MemTableLimit), + }, + { + label: i18n('text_query-execution'), + key: 'QueryExecutionConsumption', + value: getMaybeNumber(stats.QueryExecutionConsumption), + capacity: getMaybeNumber(stats.QueryExecutionLimit), + }, + { + label: i18n('text_soft-limit'), + key: 'SoftLimit', + value: getMaybeNumber(stats.SoftLimit), + }, + { + label: i18n('text_hard-limit'), + key: 'HardLimit', + value: getMaybeNumber(stats.HardLimit), + }, + ]; + + return segments.filter((segment) => segment.value !== undefined) as MemorySegment[]; +} diff --git a/src/components/ProgressViewer/ProgressViewer.tsx b/src/components/ProgressViewer/ProgressViewer.tsx index 7273078be..2176de3ca 100644 --- a/src/components/ProgressViewer/ProgressViewer.tsx +++ b/src/components/ProgressViewer/ProgressViewer.tsx @@ -95,8 +95,6 @@ export function ProgressViewer({ width: fillWidth + '%', }; - console.log(lineStyle); - const renderContent = () => { if (isNumeric(capacity) && !hideCapacity) { return `${valueText} ${divider} ${capacityText}`; diff --git a/src/components/nodesColumns/columns.tsx b/src/components/nodesColumns/columns.tsx index 081b7b193..6fda1ebee 100644 --- a/src/components/nodesColumns/columns.tsx +++ b/src/components/nodesColumns/columns.tsx @@ -103,27 +103,6 @@ export function getUptimeColumn width: 110, }; } -export function getMemoryColumn< - T extends {MemoryUsed?: string; MemoryLimit?: string}, ->(): Column { - return { - name: NODES_COLUMNS_IDS.Memory, - header: NODES_COLUMNS_TITLES.Memory, - sortAccessor: ({MemoryUsed = 0}) => Number(MemoryUsed), - defaultOrder: DataTable.DESCENDING, - render: ({row}) => ( - - ), - align: DataTable.LEFT, - width: 170, - resizeMinWidth: 170, - }; -} export function getRAMColumn(): Column { return { @@ -194,7 +173,7 @@ export function getSharedCacheUsageColumn< resizeMinWidth: 170, }; } -export function getMemoryDetailedColumn< +export function getMemoryColumn< T extends {MemoryStats?: TMemoryStats; MemoryUsed?: string; MemoryLimit?: string}, >(): Column { return { @@ -202,24 +181,19 @@ export function getMemoryDetailedColumn< header: NODES_COLUMNS_TITLES.Memory, defaultOrder: DataTable.DESCENDING, render: ({row}) => { - const totalCapacity = parseFloat(String(row.MemoryStats?.HardLimit)); - return ( + return row.MemoryStats ? ( + ) : ( + ); }, diff --git a/src/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TopNodesByMemory.tsx b/src/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TopNodesByMemory.tsx index 30fd6ce83..b543ab423 100644 --- a/src/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TopNodesByMemory.tsx +++ b/src/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TopNodesByMemory.tsx @@ -3,7 +3,7 @@ import type {Column} from '@gravity-ui/react-data-table'; import { getHostColumn, getLoadColumn, - getMemoryDetailedColumn, + getMemoryColumn, getNodeIdColumn, getSessionsColumn, getTabletsColumn, @@ -35,7 +35,7 @@ function getTopNodesByMemoryColumns( getHostColumn(params), getUptimeColumn(), getLoadColumn(), - getMemoryDetailedColumn(), + getMemoryColumn(), getSessionsColumn(), getTabletsColumn(params), ]; diff --git a/src/types/api/nodes.ts b/src/types/api/nodes.ts index 7809dc5e4..d5899d341 100644 --- a/src/types/api/nodes.ts +++ b/src/types/api/nodes.ts @@ -39,6 +39,7 @@ export interface TNodesGroup { } export interface TMemoryStats { + AnonRss: string; ExternalConsumption?: string; AllocatorCachesMemory?: string; From aca9e7fceb143e68686653095336775912a047e2 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Fri, 8 Nov 2024 14:08:33 +0300 Subject: [PATCH 03/14] fix: colors --- src/components/MemoryViewer/MemoryViewer.scss | 25 +++++---------- src/components/MemoryViewer/utils.ts | 32 ++++++++++--------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss index c5a61856b..d081bdcbd 100644 --- a/src/components/MemoryViewer/MemoryViewer.scss +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -32,24 +32,20 @@ height: 20px; margin-right: 4px; - &_type_ExternalConsumption { - background-color: var(--g-color-base-info-medium); - } - &_type_AllocatorCachesMemory { - background-color: var(--g-color-base-warning-medium); + background-color: var(--g-color-base-utility-medium-hover); } &_type_SharedCacheConsumption { - background-color: var(--g-color-base-utility-medium); + background-color: var(--g-color-base-info-medium-hover); } &_type_MemTableConsumption { - background-color: var(--g-color-base-danger-medium); + background-color: var(--g-color-base-warning-medium-hover); } &_type_QueryExecutionConsumption { - background-color: var(--g-color-base-misc-medium); + background-color: var(--g-color-base-positive-medium-hover); } } @@ -57,25 +53,20 @@ position: absolute; height: 100%; - - &_type_ExternalConsumption { - background-color: var(--g-color-base-info-medium); - } - &_type_AllocatorCachesMemory { - background-color: var(--g-color-base-warning-medium); + background-color: var(--g-color-base-utility-medium-hover); } &_type_SharedCacheConsumption { - background-color: var(--g-color-base-utility-medium); + background-color: var(--g-color-base-info-medium-hover); } &_type_MemTableConsumption { - background-color: var(--g-color-base-danger-medium); + background-color: var(--g-color-base-warning-medium-hover); } &_type_QueryExecutionConsumption { - background-color: var(--g-color-base-misc-medium); + background-color: var(--g-color-base-positive-medium-hover); } } diff --git a/src/components/MemoryViewer/utils.ts b/src/components/MemoryViewer/utils.ts index dd3e715e4..e17bdca3e 100644 --- a/src/components/MemoryViewer/utils.ts +++ b/src/components/MemoryViewer/utils.ts @@ -17,23 +17,18 @@ interface MemorySegment { export function getMemorySegments(stats: TMemoryStats): MemorySegment[] { const segments = [ - { - label: i18n('text_external-consumption'), - key: 'ExternalConsumption', - value: getMaybeNumber(stats.ExternalConsumption), - isInfo: true, - }, - { - label: i18n('text_allocator-caches'), - key: 'AllocatorCachesMemory', - value: getMaybeNumber(stats.AllocatorCachesMemory), - }, { label: i18n('text_shared-cache'), key: 'SharedCacheConsumption', value: getMaybeNumber(stats.SharedCacheConsumption), capacity: getMaybeNumber(stats.SharedCacheLimit), }, + { + label: i18n('text_query-execution'), + key: 'QueryExecutionConsumption', + value: getMaybeNumber(stats.QueryExecutionConsumption), + capacity: getMaybeNumber(stats.QueryExecutionLimit), + }, { label: i18n('text_memtable'), key: 'MemTableConsumption', @@ -41,20 +36,27 @@ export function getMemorySegments(stats: TMemoryStats): MemorySegment[] { capacity: getMaybeNumber(stats.MemTableLimit), }, { - label: i18n('text_query-execution'), - key: 'QueryExecutionConsumption', - value: getMaybeNumber(stats.QueryExecutionConsumption), - capacity: getMaybeNumber(stats.QueryExecutionLimit), + label: i18n('text_allocator-caches'), + key: 'AllocatorCachesMemory', + value: getMaybeNumber(stats.AllocatorCachesMemory), + }, + { + label: i18n('text_external-consumption'), + key: 'ExternalConsumption', + value: getMaybeNumber(stats.ExternalConsumption), + isInfo: true, }, { label: i18n('text_soft-limit'), key: 'SoftLimit', value: getMaybeNumber(stats.SoftLimit), + isInfo: true, }, { label: i18n('text_hard-limit'), key: 'HardLimit', value: getMaybeNumber(stats.HardLimit), + isInfo: true, }, ]; From 37e28147064be273c290246348ee2be3d8663483 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Mon, 11 Nov 2024 17:26:04 +0300 Subject: [PATCH 04/14] fix: issues --- src/components/MemoryViewer/MemoryViewer.scss | 87 ++++++------------- src/components/MemoryViewer/MemoryViewer.tsx | 12 ++- src/components/nodesColumns/columns.tsx | 2 +- src/utils/dataFormatters/common.ts | 3 +- src/utils/dataFormatters/dataFormatters.ts | 10 ++- 5 files changed, 43 insertions(+), 71 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss index d081bdcbd..f5a504c53 100644 --- a/src/components/MemoryViewer/MemoryViewer.scss +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -1,5 +1,16 @@ @import '../../styles/mixins.scss'; +$memory-type-colors: ( + 'AllocatorCachesMemory': var(--g-color-base-utility-medium-hover), + 'SharedCacheConsumption': var(--g-color-base-info-medium-hover), + 'MemTableConsumption': var(--g-color-base-warning-medium-hover), + 'QueryExecutionConsumption': var(--g-color-base-positive-medium-hover), +); + +@mixin memory-type-color($type) { + background-color: map-get($memory-type-colors, $type); +} + .memory-viewer { $block: &; @@ -7,94 +18,48 @@ z-index: 0; min-width: 150px; - padding: 0 4px; + padding: 0 var(--g-spacing-1); &__progress-container { position: relative; - overflow: hidden; - height: 23px; - border-radius: 2px; background: var(--g-color-base-generic); } &__container { display: flex; - align-items: end; - - text-align: end; + padding: 2px 0; } &__legend { + position: absolute; width: 20px; height: 20px; - margin-right: 4px; - - &_type_AllocatorCachesMemory { - background-color: var(--g-color-base-utility-medium-hover); - } - - &_type_SharedCacheConsumption { - background-color: var(--g-color-base-info-medium-hover); - } - - &_type_MemTableConsumption { - background-color: var(--g-color-base-warning-medium-hover); - } + border-radius: 2px; + bottom: 2px; - &_type_QueryExecutionConsumption { - background-color: var(--g-color-base-positive-medium-hover); + @each $type, $color in $memory-type-colors { + &_type_#{$type} { + @include memory-type-color($type); + } } } &__segment { position: absolute; - height: 100%; - &_type_AllocatorCachesMemory { - background-color: var(--g-color-base-utility-medium-hover); - } - - &_type_SharedCacheConsumption { - background-color: var(--g-color-base-info-medium-hover); - } - - &_type_MemTableConsumption { - background-color: var(--g-color-base-warning-medium-hover); - } - &_type_QueryExecutionConsumption { - background-color: var(--g-color-base-positive-medium-hover); + @each $type, $color in $memory-type-colors { + &_type_#{$type} { + @include memory-type-color($type); + } } } - &__legend { - display: flex; - flex-wrap: wrap; - gap: 12px; - - margin-top: 8px; - - color: var(--g-color-text-complementary); - } - - &__legend-item { - display: flex; - align-items: center; - gap: 4px; - - white-space: nowrap; - } - - &__legend-color { - flex-shrink: 0; - - width: 12px; - height: 12px; - - border-radius: 2px; + &__name { + padding-left: 28px; } &_theme_dark { diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index fbd673797..00bfc5080 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -16,6 +16,7 @@ const b = cn('memory-viewer'); type FormatProgressViewerValues = ( value?: number, capacity?: number, + precision?: number, ) => (string | number | undefined)[]; export interface MemoryProgressViewerProps { @@ -29,6 +30,8 @@ export interface MemoryProgressViewerProps { dangerThreshold?: number; } +const MEMORY_PRECISION = 2; + export function MemoryViewer({ stats, value, @@ -40,7 +43,6 @@ export function MemoryViewer({ dangerThreshold = 80, }: MemoryProgressViewerProps) { const theme = useTheme(); - let fillWidth = Math.round((parseFloat(String(value)) / parseFloat(String(capacity))) * 100) || 0; fillWidth = fillWidth > 100 ? 100 : fillWidth; @@ -52,7 +54,7 @@ export function MemoryViewer({ capacityText = ''; divider = ''; } else if (formatValues) { - [valueText, capacityText] = formatValues(Number(value), Number(capacity)); + [valueText, capacityText] = formatValues(Number(value), Number(capacity), MEMORY_PRECISION); } const renderContent = () => { @@ -106,11 +108,13 @@ export function MemoryViewer({ + formatValues(val, size, MEMORY_PRECISION) + } colorizeProgress /> ) : ( - formatValues(segmentSize)[0] + formatValues(segmentSize, undefined, MEMORY_PRECISION)[0] )} ), diff --git a/src/components/nodesColumns/columns.tsx b/src/components/nodesColumns/columns.tsx index 6fda1ebee..aee2c9f90 100644 --- a/src/components/nodesColumns/columns.tsx +++ b/src/components/nodesColumns/columns.tsx @@ -198,7 +198,7 @@ export function getMemoryColumn< ); }, align: DataTable.LEFT, - width: 500, + width: 300, resizeMinWidth: 170, }; } diff --git a/src/utils/dataFormatters/common.ts b/src/utils/dataFormatters/common.ts index 4cf38e4b5..1cd959661 100644 --- a/src/utils/dataFormatters/common.ts +++ b/src/utils/dataFormatters/common.ts @@ -22,6 +22,7 @@ export function formatValues( size?: T, delimiter?: string, withValueLabel = false, + precision?: number, ) { let calculatedSize = sizeGetter(Number(value), 0); let valueWithSizeLabel = true; @@ -37,7 +38,7 @@ export function formatValues( value, withSizeLabel: valueWithSizeLabel, size: size || calculatedSize, - precision: valuePrecision, + precision: precision ?? valuePrecision, delimiter, }); const formattedTotal = formatter({ diff --git a/src/utils/dataFormatters/dataFormatters.ts b/src/utils/dataFormatters/dataFormatters.ts index 3d9824f97..90245b1a0 100644 --- a/src/utils/dataFormatters/dataFormatters.ts +++ b/src/utils/dataFormatters/dataFormatters.ts @@ -61,6 +61,7 @@ export function formatStorageValues( size?: BytesSizes, delimiter?: string, withValueLabel?: boolean, + precision?: number, ) { return formatValues( formatBytesCustom, @@ -70,6 +71,7 @@ export function formatStorageValues( size, delimiter, withValueLabel, + precision, ); } @@ -91,12 +93,12 @@ export function formatNumericValues( ); } -export const formatStorageValuesToGb = (value?: number, total?: number) => { - return formatStorageValues(value, total, 'gb'); +export const formatStorageValuesToGb = (value?: number, total?: number, precision?: number) => { + return formatStorageValues(value, total, 'gb', undefined, undefined, precision); }; -export const formatStorageValuesToTb = (value?: number, total?: number) => { - return formatStorageValues(value, total, 'tb'); +export const formatStorageValuesToTb = (value?: number, total?: number, precision?: number) => { + return formatStorageValues(value, total, 'tb', undefined, undefined, precision); }; export const formatNumber = (number?: unknown) => { From d211fff065c4caea12730c0dcb394fdd9e36fce3 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Mon, 11 Nov 2024 17:38:42 +0300 Subject: [PATCH 05/14] fix: stylelint fix --- src/components/MemoryViewer/MemoryViewer.scss | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss index f5a504c53..63e2dcdb3 100644 --- a/src/components/MemoryViewer/MemoryViewer.scss +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -22,23 +22,29 @@ $memory-type-colors: ( &__progress-container { position: relative; + overflow: hidden; + height: 23px; + border-radius: 2px; background: var(--g-color-base-generic); } &__container { display: flex; + padding: 2px 0; } &__legend { position: absolute; + bottom: 2px; + width: 20px; height: 20px; + border-radius: 2px; - bottom: 2px; @each $type, $color in $memory-type-colors { &_type_#{$type} { @@ -49,6 +55,7 @@ $memory-type-colors: ( &__segment { position: absolute; + height: 100%; @each $type, $color in $memory-type-colors { From bcba05548795c392f164bbd1f161aced33feb59a Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Mon, 11 Nov 2024 18:15:53 +0300 Subject: [PATCH 06/14] fix: Detailed memory --- src/components/nodesColumns/i18n/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/nodesColumns/i18n/en.json b/src/components/nodesColumns/i18n/en.json index 6722c6286..4891f323f 100644 --- a/src/components/nodesColumns/i18n/en.json +++ b/src/components/nodesColumns/i18n/en.json @@ -8,7 +8,7 @@ "rack": "Rack", "version": "Version", "uptime": "Uptime", - "memory": "Memory", + "memory": "Detailed Memory", "ram": "RAM", "cpu": "CPU", "pools": "Pools", From 2bcdd1b9519ac46baa09953fce44e50f3328c028 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Mon, 11 Nov 2024 18:32:00 +0300 Subject: [PATCH 07/14] fix: fix tests --- tests/suites/nodes/nodes.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/nodes/nodes.test.ts b/tests/suites/nodes/nodes.test.ts index 90d070e8e..c8a8756c7 100644 --- a/tests/suites/nodes/nodes.test.ts +++ b/tests/suites/nodes/nodes.test.ts @@ -130,7 +130,7 @@ test.describe('Test Nodes Paginated Table', async () => { expect(rowData).toHaveProperty('Host'); expect(rowData).toHaveProperty('Uptime'); - expect(rowData).toHaveProperty('Memory'); + expect(rowData).toHaveProperty('Detailed Memory'); expect(rowData).toHaveProperty('Pools'); }); From 638fa69f56ccad3f73eab06eaab467a7607d6520 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Tue, 12 Nov 2024 16:12:32 +0300 Subject: [PATCH 08/14] fix: other memory --- src/components/MemoryViewer/MemoryViewer.scss | 1 + src/components/MemoryViewer/i18n/en.json | 1 + src/components/MemoryViewer/utils.ts | 27 ++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss index 63e2dcdb3..4371e7240 100644 --- a/src/components/MemoryViewer/MemoryViewer.scss +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -5,6 +5,7 @@ $memory-type-colors: ( 'SharedCacheConsumption': var(--g-color-base-info-medium-hover), 'MemTableConsumption': var(--g-color-base-warning-medium-hover), 'QueryExecutionConsumption': var(--g-color-base-positive-medium-hover), + 'Other': var(--g-color-base-neutral-light-hover), ); @mixin memory-type-color($type) { diff --git a/src/components/MemoryViewer/i18n/en.json b/src/components/MemoryViewer/i18n/en.json index 6c743d7d5..2d625ecf2 100644 --- a/src/components/MemoryViewer/i18n/en.json +++ b/src/components/MemoryViewer/i18n/en.json @@ -7,5 +7,6 @@ "text_query-execution": "Query Execution", "text_soft-limit": "Soft Limit", "text_hard-limit": "Hard Limit", + "text_other": "Other", "memory-detailed": "Memory Detailed" } diff --git a/src/components/MemoryViewer/utils.ts b/src/components/MemoryViewer/utils.ts index e17bdca3e..8e4eaa33b 100644 --- a/src/components/MemoryViewer/utils.ts +++ b/src/components/MemoryViewer/utils.ts @@ -22,24 +22,49 @@ export function getMemorySegments(stats: TMemoryStats): MemorySegment[] { key: 'SharedCacheConsumption', value: getMaybeNumber(stats.SharedCacheConsumption), capacity: getMaybeNumber(stats.SharedCacheLimit), + isInfo: false, }, { label: i18n('text_query-execution'), key: 'QueryExecutionConsumption', value: getMaybeNumber(stats.QueryExecutionConsumption), capacity: getMaybeNumber(stats.QueryExecutionLimit), + isInfo: false, }, { label: i18n('text_memtable'), key: 'MemTableConsumption', value: getMaybeNumber(stats.MemTableConsumption), capacity: getMaybeNumber(stats.MemTableLimit), + isInfo: false, }, { label: i18n('text_allocator-caches'), key: 'AllocatorCachesMemory', value: getMaybeNumber(stats.AllocatorCachesMemory), + isInfo: false, }, + ]; + + const nonInfoSegments = segments.filter( + (segment) => segment.value !== undefined, + ) as MemorySegment[]; + const sumNonInfoSegments = nonInfoSegments.reduce((acc, segment) => acc + segment.value, 0); + + const totalMemory = getMaybeNumber(stats.AnonRss); + + if (totalMemory) { + const otherMemory = Math.max(0, totalMemory - sumNonInfoSegments); + + segments.push({ + label: i18n('text_other'), + key: 'Other', + value: otherMemory, + isInfo: false, + }); + } + + segments.push( { label: i18n('text_external-consumption'), key: 'ExternalConsumption', @@ -58,7 +83,7 @@ export function getMemorySegments(stats: TMemoryStats): MemorySegment[] { value: getMaybeNumber(stats.HardLimit), isInfo: true, }, - ]; + ); return segments.filter((segment) => segment.value !== undefined) as MemorySegment[]; } From 84043360292be18f4d44cdd57c4245e81c616f4d Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Tue, 12 Nov 2024 16:16:40 +0300 Subject: [PATCH 09/14] fix: lower precision --- src/components/MemoryViewer/MemoryViewer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index 00bfc5080..343f6dcd5 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -30,7 +30,7 @@ export interface MemoryProgressViewerProps { dangerThreshold?: number; } -const MEMORY_PRECISION = 2; +const MEMORY_PRECISION = 1; export function MemoryViewer({ stats, From 570f883995d14dd4fe3ae148c81f1822f5ff2b1c Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Tue, 12 Nov 2024 16:23:50 +0300 Subject: [PATCH 10/14] fix: rm precision --- src/components/MemoryViewer/MemoryViewer.tsx | 11 +++-------- src/utils/dataFormatters/common.ts | 3 +-- src/utils/dataFormatters/dataFormatters.ts | 10 ++++------ 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index 343f6dcd5..d7d126728 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -16,7 +16,6 @@ const b = cn('memory-viewer'); type FormatProgressViewerValues = ( value?: number, capacity?: number, - precision?: number, ) => (string | number | undefined)[]; export interface MemoryProgressViewerProps { @@ -30,8 +29,6 @@ export interface MemoryProgressViewerProps { dangerThreshold?: number; } -const MEMORY_PRECISION = 1; - export function MemoryViewer({ stats, value, @@ -54,7 +51,7 @@ export function MemoryViewer({ capacityText = ''; divider = ''; } else if (formatValues) { - [valueText, capacityText] = formatValues(Number(value), Number(capacity), MEMORY_PRECISION); + [valueText, capacityText] = formatValues(Number(value), Number(capacity)); } const renderContent = () => { @@ -108,13 +105,11 @@ export function MemoryViewer({ - formatValues(val, size, MEMORY_PRECISION) - } + formatValues={formatValues} colorizeProgress /> ) : ( - formatValues(segmentSize, undefined, MEMORY_PRECISION)[0] + formatValues(segmentSize, undefined)[0] )} ), diff --git a/src/utils/dataFormatters/common.ts b/src/utils/dataFormatters/common.ts index 1cd959661..4cf38e4b5 100644 --- a/src/utils/dataFormatters/common.ts +++ b/src/utils/dataFormatters/common.ts @@ -22,7 +22,6 @@ export function formatValues( size?: T, delimiter?: string, withValueLabel = false, - precision?: number, ) { let calculatedSize = sizeGetter(Number(value), 0); let valueWithSizeLabel = true; @@ -38,7 +37,7 @@ export function formatValues( value, withSizeLabel: valueWithSizeLabel, size: size || calculatedSize, - precision: precision ?? valuePrecision, + precision: valuePrecision, delimiter, }); const formattedTotal = formatter({ diff --git a/src/utils/dataFormatters/dataFormatters.ts b/src/utils/dataFormatters/dataFormatters.ts index 90245b1a0..3d9824f97 100644 --- a/src/utils/dataFormatters/dataFormatters.ts +++ b/src/utils/dataFormatters/dataFormatters.ts @@ -61,7 +61,6 @@ export function formatStorageValues( size?: BytesSizes, delimiter?: string, withValueLabel?: boolean, - precision?: number, ) { return formatValues( formatBytesCustom, @@ -71,7 +70,6 @@ export function formatStorageValues( size, delimiter, withValueLabel, - precision, ); } @@ -93,12 +91,12 @@ export function formatNumericValues( ); } -export const formatStorageValuesToGb = (value?: number, total?: number, precision?: number) => { - return formatStorageValues(value, total, 'gb', undefined, undefined, precision); +export const formatStorageValuesToGb = (value?: number, total?: number) => { + return formatStorageValues(value, total, 'gb'); }; -export const formatStorageValuesToTb = (value?: number, total?: number, precision?: number) => { - return formatStorageValues(value, total, 'tb', undefined, undefined, precision); +export const formatStorageValuesToTb = (value?: number, total?: number) => { + return formatStorageValues(value, total, 'tb'); }; export const formatNumber = (number?: unknown) => { From dfdfa28701507d58301e8bf072c8ad249784609e Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Tue, 12 Nov 2024 16:51:00 +0300 Subject: [PATCH 11/14] Revert "fix: rm precision" This reverts commit 570f883995d14dd4fe3ae148c81f1822f5ff2b1c. --- src/components/MemoryViewer/MemoryViewer.tsx | 11 ++++++++--- src/utils/dataFormatters/common.ts | 3 ++- src/utils/dataFormatters/dataFormatters.ts | 10 ++++++---- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index d7d126728..343f6dcd5 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -16,6 +16,7 @@ const b = cn('memory-viewer'); type FormatProgressViewerValues = ( value?: number, capacity?: number, + precision?: number, ) => (string | number | undefined)[]; export interface MemoryProgressViewerProps { @@ -29,6 +30,8 @@ export interface MemoryProgressViewerProps { dangerThreshold?: number; } +const MEMORY_PRECISION = 1; + export function MemoryViewer({ stats, value, @@ -51,7 +54,7 @@ export function MemoryViewer({ capacityText = ''; divider = ''; } else if (formatValues) { - [valueText, capacityText] = formatValues(Number(value), Number(capacity)); + [valueText, capacityText] = formatValues(Number(value), Number(capacity), MEMORY_PRECISION); } const renderContent = () => { @@ -105,11 +108,13 @@ export function MemoryViewer({ + formatValues(val, size, MEMORY_PRECISION) + } colorizeProgress /> ) : ( - formatValues(segmentSize, undefined)[0] + formatValues(segmentSize, undefined, MEMORY_PRECISION)[0] )} ), diff --git a/src/utils/dataFormatters/common.ts b/src/utils/dataFormatters/common.ts index 4cf38e4b5..1cd959661 100644 --- a/src/utils/dataFormatters/common.ts +++ b/src/utils/dataFormatters/common.ts @@ -22,6 +22,7 @@ export function formatValues( size?: T, delimiter?: string, withValueLabel = false, + precision?: number, ) { let calculatedSize = sizeGetter(Number(value), 0); let valueWithSizeLabel = true; @@ -37,7 +38,7 @@ export function formatValues( value, withSizeLabel: valueWithSizeLabel, size: size || calculatedSize, - precision: valuePrecision, + precision: precision ?? valuePrecision, delimiter, }); const formattedTotal = formatter({ diff --git a/src/utils/dataFormatters/dataFormatters.ts b/src/utils/dataFormatters/dataFormatters.ts index 3d9824f97..90245b1a0 100644 --- a/src/utils/dataFormatters/dataFormatters.ts +++ b/src/utils/dataFormatters/dataFormatters.ts @@ -61,6 +61,7 @@ export function formatStorageValues( size?: BytesSizes, delimiter?: string, withValueLabel?: boolean, + precision?: number, ) { return formatValues( formatBytesCustom, @@ -70,6 +71,7 @@ export function formatStorageValues( size, delimiter, withValueLabel, + precision, ); } @@ -91,12 +93,12 @@ export function formatNumericValues( ); } -export const formatStorageValuesToGb = (value?: number, total?: number) => { - return formatStorageValues(value, total, 'gb'); +export const formatStorageValuesToGb = (value?: number, total?: number, precision?: number) => { + return formatStorageValues(value, total, 'gb', undefined, undefined, precision); }; -export const formatStorageValuesToTb = (value?: number, total?: number) => { - return formatStorageValues(value, total, 'tb'); +export const formatStorageValuesToTb = (value?: number, total?: number, precision?: number) => { + return formatStorageValues(value, total, 'tb', undefined, undefined, precision); }; export const formatNumber = (number?: unknown) => { From 6ec984240eab1a65453f72192b3b19bcff3404df Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Tue, 12 Nov 2024 17:15:43 +0300 Subject: [PATCH 12/14] Revert "Revert "fix: rm precision"" This reverts commit dfdfa28701507d58301e8bf072c8ad249784609e. --- src/components/MemoryViewer/MemoryViewer.tsx | 11 +++-------- src/utils/dataFormatters/common.ts | 3 +-- src/utils/dataFormatters/dataFormatters.ts | 10 ++++------ 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index 343f6dcd5..d7d126728 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -16,7 +16,6 @@ const b = cn('memory-viewer'); type FormatProgressViewerValues = ( value?: number, capacity?: number, - precision?: number, ) => (string | number | undefined)[]; export interface MemoryProgressViewerProps { @@ -30,8 +29,6 @@ export interface MemoryProgressViewerProps { dangerThreshold?: number; } -const MEMORY_PRECISION = 1; - export function MemoryViewer({ stats, value, @@ -54,7 +51,7 @@ export function MemoryViewer({ capacityText = ''; divider = ''; } else if (formatValues) { - [valueText, capacityText] = formatValues(Number(value), Number(capacity), MEMORY_PRECISION); + [valueText, capacityText] = formatValues(Number(value), Number(capacity)); } const renderContent = () => { @@ -108,13 +105,11 @@ export function MemoryViewer({ - formatValues(val, size, MEMORY_PRECISION) - } + formatValues={formatValues} colorizeProgress /> ) : ( - formatValues(segmentSize, undefined, MEMORY_PRECISION)[0] + formatValues(segmentSize, undefined)[0] )} ), diff --git a/src/utils/dataFormatters/common.ts b/src/utils/dataFormatters/common.ts index 1cd959661..4cf38e4b5 100644 --- a/src/utils/dataFormatters/common.ts +++ b/src/utils/dataFormatters/common.ts @@ -22,7 +22,6 @@ export function formatValues( size?: T, delimiter?: string, withValueLabel = false, - precision?: number, ) { let calculatedSize = sizeGetter(Number(value), 0); let valueWithSizeLabel = true; @@ -38,7 +37,7 @@ export function formatValues( value, withSizeLabel: valueWithSizeLabel, size: size || calculatedSize, - precision: precision ?? valuePrecision, + precision: valuePrecision, delimiter, }); const formattedTotal = formatter({ diff --git a/src/utils/dataFormatters/dataFormatters.ts b/src/utils/dataFormatters/dataFormatters.ts index 90245b1a0..3d9824f97 100644 --- a/src/utils/dataFormatters/dataFormatters.ts +++ b/src/utils/dataFormatters/dataFormatters.ts @@ -61,7 +61,6 @@ export function formatStorageValues( size?: BytesSizes, delimiter?: string, withValueLabel?: boolean, - precision?: number, ) { return formatValues( formatBytesCustom, @@ -71,7 +70,6 @@ export function formatStorageValues( size, delimiter, withValueLabel, - precision, ); } @@ -93,12 +91,12 @@ export function formatNumericValues( ); } -export const formatStorageValuesToGb = (value?: number, total?: number, precision?: number) => { - return formatStorageValues(value, total, 'gb', undefined, undefined, precision); +export const formatStorageValuesToGb = (value?: number, total?: number) => { + return formatStorageValues(value, total, 'gb'); }; -export const formatStorageValuesToTb = (value?: number, total?: number, precision?: number) => { - return formatStorageValues(value, total, 'tb', undefined, undefined, precision); +export const formatStorageValuesToTb = (value?: number, total?: number) => { + return formatStorageValues(value, total, 'tb'); }; export const formatNumber = (number?: unknown) => { From 45041ca3ebafd6781c6f20caacf517ad1dfd2941 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Wed, 13 Nov 2024 11:36:14 +0300 Subject: [PATCH 13/14] fix: review fixes --- src/components/MemoryViewer/MemoryViewer.scss | 11 +---------- src/components/MemoryViewer/MemoryViewer.tsx | 16 ++++++++-------- src/components/MemoryViewer/i18n/en.json | 5 ++--- src/components/MemoryViewer/utils.ts | 6 ++++++ src/components/nodesColumns/i18n/en.json | 1 - 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.scss b/src/components/MemoryViewer/MemoryViewer.scss index 4371e7240..049df2db4 100644 --- a/src/components/MemoryViewer/MemoryViewer.scss +++ b/src/components/MemoryViewer/MemoryViewer.scss @@ -26,7 +26,7 @@ $memory-type-colors: ( overflow: hidden; - height: 23px; + height: 20px; border-radius: 2px; background: var(--g-color-base-generic); @@ -96,15 +96,6 @@ $memory-type-colors: ( } } - &_size { - height: 20px; - @include body-2-typography(); - - #{$block}__progress-container { - height: inherit; - } - } - &__text { display: flex; justify-content: center; diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index d7d126728..d73fd1754 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -1,6 +1,7 @@ import {DefinitionList, useTheme} from '@gravity-ui/uikit'; import type {TMemoryStats} from '../../types/api/nodes'; +import {formatBytes} from '../../utils/bytesParsers'; import {cn} from '../../utils/cn'; import {calculateProgressStatus} from '../../utils/progress'; import {isNumeric} from '../../utils/utils'; @@ -71,14 +72,8 @@ export function MemoryViewer({ const memorySegments = getMemorySegments(stats); - const totalUsedMemory = - memorySegments - .filter(({isInfo}) => !isInfo) - .reduce((acc, segment) => acc + calculateMemoryShare(segment.value), 0) / - parseFloat(String(capacity)); - const status = calculateProgressStatus({ - fillWidth: totalUsedMemory, + fillWidth, warningThreshold, dangerThreshold, colorizeProgress: true, @@ -109,7 +104,12 @@ export function MemoryViewer({ colorizeProgress /> ) : ( - formatValues(segmentSize, undefined)[0] + formatBytes({ + value: segmentSize, + size: 'gb', + withSizeLabel: true, + precision: 2, + }) )} ), diff --git a/src/components/MemoryViewer/i18n/en.json b/src/components/MemoryViewer/i18n/en.json index 2d625ecf2..4f51efc6b 100644 --- a/src/components/MemoryViewer/i18n/en.json +++ b/src/components/MemoryViewer/i18n/en.json @@ -1,12 +1,11 @@ { - "text_memory-detailed": "Memory Detailed", "text_external-consumption": "External Consumption", "text_allocator-caches": "Allocator Caches", "text_shared-cache": "Shared Cache", "text_memtable": "MemTable", "text_query-execution": "Query Execution", + "text_usage": "Usage", "text_soft-limit": "Soft Limit", "text_hard-limit": "Hard Limit", - "text_other": "Other", - "memory-detailed": "Memory Detailed" + "text_other": "Other" } diff --git a/src/components/MemoryViewer/utils.ts b/src/components/MemoryViewer/utils.ts index 8e4eaa33b..e6504c6de 100644 --- a/src/components/MemoryViewer/utils.ts +++ b/src/components/MemoryViewer/utils.ts @@ -71,6 +71,12 @@ export function getMemorySegments(stats: TMemoryStats): MemorySegment[] { value: getMaybeNumber(stats.ExternalConsumption), isInfo: true, }, + { + label: i18n('text_usage'), + key: 'Usage', + value: getMaybeNumber(stats.AnonRss), + isInfo: true, + }, { label: i18n('text_soft-limit'), key: 'SoftLimit', diff --git a/src/components/nodesColumns/i18n/en.json b/src/components/nodesColumns/i18n/en.json index 4891f323f..a1f1e297d 100644 --- a/src/components/nodesColumns/i18n/en.json +++ b/src/components/nodesColumns/i18n/en.json @@ -15,7 +15,6 @@ "disk-usage": "Disk usage", "tablets": "Tablets", "load-average": "Load Average", - "memory-detailed": "Memory Detailed", "load": "Load", "caches": "Caches", "sessions": "Sessions", From 4595c070864ce465822bbd293883598756588344 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Wed, 13 Nov 2024 12:10:04 +0300 Subject: [PATCH 14/14] fix: min visible share --- src/components/MemoryViewer/MemoryViewer.tsx | 39 +++++++++++++++---- .../ProgressViewer/ProgressViewer.tsx | 2 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/components/MemoryViewer/MemoryViewer.tsx b/src/components/MemoryViewer/MemoryViewer.tsx index d73fd1754..65b1b23ba 100644 --- a/src/components/MemoryViewer/MemoryViewer.tsx +++ b/src/components/MemoryViewer/MemoryViewer.tsx @@ -3,21 +3,38 @@ import {DefinitionList, useTheme} from '@gravity-ui/uikit'; import type {TMemoryStats} from '../../types/api/nodes'; import {formatBytes} from '../../utils/bytesParsers'; import {cn} from '../../utils/cn'; +import {GIGABYTE} from '../../utils/constants'; import {calculateProgressStatus} from '../../utils/progress'; import {isNumeric} from '../../utils/utils'; import {HoverPopup} from '../HoverPopup/HoverPopup'; +import type {FormatProgressViewerValues} from '../ProgressViewer/ProgressViewer'; import {ProgressViewer} from '../ProgressViewer/ProgressViewer'; import {getMemorySegments} from './utils'; import './MemoryViewer.scss'; +const MIN_VISIBLE_MEMORY_SHARE = 1; +const MIN_VISIBLE_MEMORY_VALUE = 0.01 * GIGABYTE; + const b = cn('memory-viewer'); -type FormatProgressViewerValues = ( - value?: number, - capacity?: number, -) => (string | number | undefined)[]; +const formatDetailedValues: FormatProgressViewerValues = (value, total) => { + return [ + formatBytes({ + value, + size: 'gb', + withSizeLabel: false, + precision: 2, + }), + formatBytes({ + value: total, + size: 'gb', + withSizeLabel: true, + precision: 1, + }), + ]; +}; export interface MemoryProgressViewerProps { stats: TMemoryStats; @@ -100,7 +117,7 @@ export function MemoryViewer({ ) : ( @@ -122,15 +139,23 @@ export function MemoryViewer({ {memorySegments .filter(({isInfo}) => !isInfo) .map((segment) => { + if (segment.value < MIN_VISIBLE_MEMORY_VALUE) { + return null; + } + + const currentMemoryShare = Math.max( + calculateMemoryShare(segment.value), + MIN_VISIBLE_MEMORY_SHARE, + ); const position = currentPosition; - currentPosition += calculateMemoryShare(segment.value); + currentPosition += currentMemoryShare; return (
diff --git a/src/components/ProgressViewer/ProgressViewer.tsx b/src/components/ProgressViewer/ProgressViewer.tsx index 2176de3ca..d0a45f56d 100644 --- a/src/components/ProgressViewer/ProgressViewer.tsx +++ b/src/components/ProgressViewer/ProgressViewer.tsx @@ -11,7 +11,7 @@ const b = cn('progress-viewer'); type ProgressViewerSize = 'xs' | 's' | 'ns' | 'm' | 'n' | 'l' | 'head'; -type FormatProgressViewerValues = ( +export type FormatProgressViewerValues = ( value?: number, capacity?: number, ) => (string | number | undefined)[];