Skip to content

Commit 0d4ccf2

Browse files
authored
feat: add top nodes by memory table (#562)
1 parent 3048f84 commit 0d4ccf2

File tree

15 files changed

+259
-26
lines changed

15 files changed

+259
-26
lines changed

src/containers/Nodes/getNodesColumns.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ import {PoolsGraph} from '../../components/PoolsGraph/PoolsGraph';
55
import {ProgressViewer} from '../../components/ProgressViewer/ProgressViewer';
66
import {TabletsStatistic} from '../../components/TabletsStatistic';
77
import {NodeHostWrapper} from '../../components/NodeHostWrapper/NodeHostWrapper';
8-
import {formatBytesToGigabyte} from '../../utils/dataFormatters/dataFormatters';
8+
import {
9+
formatBytesToGigabyte,
10+
formatStorageValuesToGb,
11+
} from '../../utils/dataFormatters/dataFormatters';
912
import type {NodesPreparedEntity} from '../../store/reducers/nodes/types';
1013
import type {GetNodeRefFunc} from '../../types/additionalProps';
11-
import {getLoadSeverityForNode} from '../../store/reducers/tenantOverview/topNodesByLoad/utils';
14+
import {getLoadSeverityForNode} from '../../store/reducers/nodes/utils';
1215
import {UsageLabel} from '../../components/UsageLabel/UsageLabel';
1316

1417
const NODES_COLUMNS_IDS = {
@@ -23,6 +26,7 @@ const NODES_COLUMNS_IDS = {
2326
LoadAverage: 'LoadAverage',
2427
Tablets: 'Tablets',
2528
TopNodesLoadAverage: 'TopNodesLoadAverage',
29+
TopNodesMemory: 'TopNodesMemory',
2630
};
2731

2832
interface GetNodesColumnsProps {
@@ -83,6 +87,7 @@ const uptimeColumn: Column<NodesPreparedEntity> = {
8387
sortAccessor: ({StartTime}) => StartTime && -StartTime,
8488
align: DataTable.RIGHT,
8589
width: '110px',
90+
sortable: false,
8691
};
8792

8893
const memoryColumn: Column<NodesPreparedEntity> = {
@@ -149,6 +154,7 @@ const getTabletsColumn = (tabletsPath?: string): Column<NodesPreparedEntity> =>
149154
);
150155
},
151156
align: DataTable.LEFT,
157+
sortable: false,
152158
});
153159

154160
const topNodesLoadAverageColumn: Column<NodesPreparedEntity> = {
@@ -168,6 +174,25 @@ const topNodesLoadAverageColumn: Column<NodesPreparedEntity> = {
168174
sortable: false,
169175
};
170176

177+
const topNodesMemoryColumn: Column<NodesPreparedEntity> = {
178+
name: NODES_COLUMNS_IDS.TopNodesMemory,
179+
header: 'Memory',
180+
render: ({row}) =>
181+
row.MemoryUsed ? (
182+
<ProgressViewer
183+
value={row.MemoryUsed}
184+
capacity={row.MemoryLimit}
185+
formatValues={formatStorageValuesToGb}
186+
colorizeProgress={true}
187+
/>
188+
) : (
189+
'—'
190+
),
191+
align: DataTable.LEFT,
192+
width: '140px',
193+
sortable: false,
194+
};
195+
171196
export function getNodesColumns({
172197
tabletsPath,
173198
getNodeRef,
@@ -197,3 +222,17 @@ export function getTopNodesByCpuColumns(
197222
): Column<NodesPreparedEntity>[] {
198223
return [cpuColumn, nodeIdColumn, getHostColumn(getNodeRef)];
199224
}
225+
226+
export function getTopNodesByMemoryColumns({
227+
tabletsPath,
228+
getNodeRef,
229+
}: GetNodesColumnsProps): Column<NodesPreparedEntity>[] {
230+
return [
231+
nodeIdColumn,
232+
getHostColumn(getNodeRef, true),
233+
uptimeColumn,
234+
topNodesMemoryColumn,
235+
topNodesLoadAverageColumn,
236+
getTabletsColumn(tabletsPath),
237+
];
238+
}

src/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
flex-direction: column;
1212

1313
min-width: 300px;
14-
height: max-content;
1514
}
1615

1716
&__modal {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {TopNodesByMemory} from './TopNodesByMemory';
2+
3+
interface TenantMemoryProps {
4+
path: string;
5+
}
6+
7+
export function TenantMemory({path}: TenantMemoryProps) {
8+
return <TopNodesByMemory path={path} />;
9+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {useDispatch} from 'react-redux';
2+
import {useCallback} from 'react';
3+
4+
import {useAutofetcher, useTypedSelector} from '../../../../../utils/hooks';
5+
import {
6+
getTopNodesByMemory,
7+
selectTopNodesByMemory,
8+
setDataWasNotLoaded,
9+
} from '../../../../../store/reducers/tenantOverview/topNodesByMemory/topNodesByMemory';
10+
import type {AdditionalNodesProps} from '../../../../../types/additionalProps';
11+
import {getTopNodesByMemoryColumns} from '../../../../Nodes/getNodesColumns';
12+
import {TenantOverviewTableLayout} from '../TenantOverviewTableLayout';
13+
14+
import i18n from '../i18n';
15+
16+
interface TopNodesByMemoryProps {
17+
path: string;
18+
additionalNodesProps?: AdditionalNodesProps;
19+
}
20+
21+
export function TopNodesByMemory({path, additionalNodesProps}: TopNodesByMemoryProps) {
22+
const dispatch = useDispatch();
23+
24+
const {wasLoaded, loading, error} = useTypedSelector((state) => state.topNodesByMemory);
25+
const {autorefresh} = useTypedSelector((state) => state.schema);
26+
const topNodes = useTypedSelector(selectTopNodesByMemory);
27+
const columns = getTopNodesByMemoryColumns({
28+
getNodeRef: additionalNodesProps?.getNodeRef,
29+
});
30+
31+
const fetchNodes = useCallback(
32+
(isBackground) => {
33+
if (!isBackground) {
34+
dispatch(setDataWasNotLoaded());
35+
}
36+
37+
dispatch(getTopNodesByMemory({tenant: path}));
38+
},
39+
[dispatch, path],
40+
);
41+
42+
useAutofetcher(fetchNodes, [fetchNodes], autorefresh);
43+
44+
return (
45+
<TenantOverviewTableLayout
46+
data={topNodes || []}
47+
columns={columns}
48+
title="Top nodes by memory"
49+
loading={loading}
50+
wasLoaded={wasLoaded}
51+
error={error}
52+
emptyDataMessage={i18n('top-nodes.empty-data')}
53+
/>
54+
);
55+
}

src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
@import '../../../../styles/mixins.scss';
22

33
.tenant-overview {
4+
overflow: auto;
5+
6+
height: 100%;
47
padding-bottom: 20px;
58

69
&__loader {
@@ -81,6 +84,13 @@
8184
line-height: var(--yc-text-body-2-line-height);
8285
}
8386

87+
&__info {
88+
position: sticky;
89+
left: 0;
90+
91+
width: max-content;
92+
}
93+
8494
&__title {
8595
margin-bottom: 10px;
8696

src/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import {TenantCpu} from './TenantCpu/TenantCpu';
1616
import {HealthcheckDetails} from './Healthcheck/HealthcheckDetails';
1717
import {MetricsCards, type TenantMetrics} from './MetricsCards/MetricsCards';
1818
import {TenantStorage} from './TenantStorage/TenantStorage';
19+
import {TenantMemory} from './TenantMemory/TenantMemory';
1920
import {useHealthcheck} from './useHealthcheck';
2021

21-
import i18n from './i18n';
2222
import './TenantOverview.scss';
2323

2424
const b = cn('tenant-overview');
@@ -127,7 +127,7 @@ export function TenantOverview({
127127
return <TenantStorage tenantName={tenantName} metrics={storageMetrics} />;
128128
}
129129
case TENANT_METRICS_TABS_IDS.memory: {
130-
return i18n('label.under-development');
130+
return <TenantMemory path={tenantName} />;
131131
}
132132
case TENANT_METRICS_TABS_IDS.healthcheck: {
133133
return <HealthcheckDetails issueTrees={issueTrees} error={healthcheckError} />;
@@ -148,19 +148,21 @@ export function TenantOverview({
148148

149149
return (
150150
<div className={b()}>
151-
<div className={b('top-label')}>{tenantType}</div>
152-
<div className={b('top')}>
153-
{renderName()}
154-
{additionalTenantProps?.getMonitoringLink?.(Name, Type)}
151+
<div className={b('info')}>
152+
<div className={b('top-label')}>{tenantType}</div>
153+
<div className={b('top')}>
154+
{renderName()}
155+
{additionalTenantProps?.getMonitoringLink?.(Name, Type)}
156+
</div>
157+
<MetricsCards
158+
metrics={calculatedMetrics}
159+
issuesStatistics={issuesStatistics}
160+
selfCheckResult={selfCheckResult}
161+
fetchHealthcheck={fetchHealthcheck}
162+
healthcheckLoading={healthcheckLoading}
163+
healthcheckError={healthcheckError}
164+
/>
155165
</div>
156-
<MetricsCards
157-
metrics={calculatedMetrics}
158-
issuesStatistics={issuesStatistics}
159-
selfCheckResult={selfCheckResult}
160-
fetchHealthcheck={fetchHealthcheck}
161-
healthcheckLoading={healthcheckLoading}
162-
healthcheckError={healthcheckError}
163-
/>
164166
{renderTabContent()}
165167
</div>
166168
);

src/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@
77
"title.pools": "Pools",
88
"title.metrics": "Metrics",
99

10-
"top-groups.empty-data": "No such groups",
11-
12-
"label.under-development": "This section is under development"
10+
"top-groups.empty-data": "No such groups"
1311
}

src/containers/Tenant/Diagnostics/TenantOverview/i18n/ru.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@
77
"title.pools": "Пулы",
88
"title.metrics": "Метрики",
99

10-
"top-groups.empty-data": "Нет групп",
11-
12-
"label.under-development": "Этот раздел находится в разработке"
10+
"top-groups.empty-data": "Нет групп"
1311
}

src/store/reducers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {combineReducers} from 'redux';
33
import nodes from './nodes/nodes';
44
import {topNodesByLoad} from './tenantOverview/topNodesByLoad/topNodesByLoad';
55
import {topNodesByCpu} from './tenantOverview/topNodesByCpu/topNodesByCpu';
6+
import {topNodesByMemory} from './tenantOverview/topNodesByMemory/topNodesByMemory';
67
import cluster from './cluster/cluster';
78
import clusterNodes from './clusterNodes/clusterNodes';
89
import tenant from './tenant/tenant';
@@ -47,6 +48,7 @@ export const rootReducer = {
4748
nodes,
4849
topNodesByLoad,
4950
topNodesByCpu,
51+
topNodesByMemory,
5052
cluster,
5153
clusterNodes,
5254
tenant,

src/store/reducers/nodes/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export interface NodesPreparedEntity {
3333
StartTime?: string;
3434
Uptime: string;
3535
MemoryUsed?: string;
36+
MemoryLimit?: string;
3637
PoolStats?: TPoolStats[];
3738
LoadAverage?: number[];
3839
Tablets?: TFullTabletStateInfo[] | TComputeTabletStateInfo[];

0 commit comments

Comments
 (0)