Skip to content

Commit 08e9fe0

Browse files
feat(Overview): display topic stats for topics and streams
1 parent c74cd9d commit 08e9fe0

File tree

30 files changed

+514
-153
lines changed

30 files changed

+514
-153
lines changed

src/components/InfoViewer/InfoViewer.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@
4242
color: var(--yc-color-text-secondary);
4343
}
4444

45+
&__label-text {
46+
&_multiline {
47+
overflow: visible;
48+
49+
max-width: 180px;
50+
51+
white-space: normal;
52+
}
53+
}
54+
4555
&__dots {
4656
display: flex;
4757
flex: 1 1 auto;

src/components/InfoViewer/InfoViewer.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,29 @@ interface InfoViewerProps {
1414
dots?: boolean;
1515
size?: 's';
1616
className?: string;
17+
multilineLabels?: boolean;
1718
}
1819

1920
const b = cn('info-viewer');
2021

21-
const InfoViewer = ({title, info, dots = true, size, className}: InfoViewerProps) => (
22+
const InfoViewer = ({
23+
title,
24+
info,
25+
dots = true,
26+
size,
27+
className,
28+
multilineLabels,
29+
}: InfoViewerProps) => (
2230
<div className={b({size}, className)}>
2331
{title && <div className={b('title')}>{title}</div>}
2432
{info && info.length > 0 ? (
2533
<div className={b('items')}>
2634
{info.map((data, infoIndex) => (
2735
<div className={b('row')} key={data.label + infoIndex}>
2836
<div className={b('label')}>
29-
{data.label}
37+
<div className={b('label-text', {multiline: multilineLabels})}>
38+
{data.label}
39+
</div>
3040
{dots && <div className={b('dots')} />}
3141
</div>
3242

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {TCdcStreamDescription} from '../../../types/api/schema';
2+
3+
import {createInfoFormatter} from '../utils';
4+
5+
export const formatCdcStreamItem = createInfoFormatter<TCdcStreamDescription>({
6+
values: {
7+
Mode: (value) => value?.substring('ECdcStreamMode'.length),
8+
Format: (value) => value?.substring('ECdcStreamFormat'.length),
9+
},
10+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
export * from './common';
22
export * from './schema';
3+
export * from './topicStats';
4+
export * from './pqGroup';
5+
export * from './cdcStream';
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {
2+
EMeteringMode,
3+
TPersQueueGroupDescription,
4+
TPQPartitionConfig,
5+
TPQTabletConfig,
6+
} from '../../../types/api/schema';
7+
import {formatBps, formatBytes, formatNumber} from '../../../utils';
8+
import {HOUR_IN_SECONDS} from '../../../utils/constants';
9+
10+
import {createInfoFormatter} from '../utils';
11+
12+
const EMeteringModeToNames: Record<EMeteringMode, string> = {
13+
[EMeteringMode.METERING_MODE_REQUEST_UNITS]: 'request-units',
14+
[EMeteringMode.METERING_MODE_RESERVED_CAPACITY]: 'reserved-capacity',
15+
};
16+
17+
export const formatPQGroupItem = createInfoFormatter<TPersQueueGroupDescription>({
18+
values: {
19+
Partitions: (value) => formatNumber(value?.length || 0),
20+
PQTabletConfig: (value) => {
21+
const hours =
22+
Math.round((value.PartitionConfig.LifetimeSeconds / HOUR_IN_SECONDS) * 100) / 100;
23+
return `${formatNumber(hours)} hours`;
24+
},
25+
},
26+
labels: {
27+
Partitions: 'Partitions count',
28+
PQTabletConfig: 'Retention',
29+
},
30+
});
31+
32+
export const formatPQTabletConfig = createInfoFormatter<TPQTabletConfig>({
33+
values: {
34+
Codecs: (value) => value && Object.values(value.Codecs || {}).join(', '),
35+
MeteringMode: (value) => value && EMeteringModeToNames[value],
36+
},
37+
labels: {
38+
MeteringMode: 'Metering mode',
39+
},
40+
});
41+
42+
export const formatPQPartitionConfig = createInfoFormatter<TPQPartitionConfig>({
43+
values: {
44+
StorageLimitBytes: formatBytes,
45+
WriteSpeedInBytesPerSecond: formatBps,
46+
},
47+
labels: {
48+
StorageLimitBytes: 'Retention storage',
49+
WriteSpeedInBytesPerSecond: 'Partitions write speed',
50+
},
51+
});
Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import type {
2-
TCdcStreamDescription,
3-
TIndexDescription,
4-
TPersQueueGroupDescription,
5-
} from '../../../types/api/schema';
6-
import {formatNumber} from '../../../utils';
7-
import {HOUR_IN_SECONDS} from '../../../utils/constants';
1+
import {TIndexDescription} from '../../../types/api/schema';
82

93
import {createInfoFormatter} from '../utils';
104

@@ -20,25 +14,3 @@ export const formatTableIndexItem = createInfoFormatter<TIndexDescription>({
2014
DataColumnNames: 'Includes',
2115
},
2216
});
23-
24-
export const formatCdcStreamItem = createInfoFormatter<TCdcStreamDescription>({
25-
values: {
26-
Mode: (value) => value?.substring('ECdcStreamMode'.length),
27-
Format: (value) => value?.substring('ECdcStreamFormat'.length),
28-
},
29-
});
30-
31-
export const formatPQGroupItem = createInfoFormatter<TPersQueueGroupDescription>({
32-
values: {
33-
Partitions: (value) => formatNumber(value?.length || 0),
34-
PQTabletConfig: (value) => {
35-
const hours =
36-
Math.round((value.PartitionConfig.LifetimeSeconds / HOUR_IN_SECONDS) * 100) / 100;
37-
return `${formatNumber(hours)} hours`;
38-
},
39-
},
40-
labels: {
41-
Partitions: 'Partitions count',
42-
PQTabletConfig: 'Retention',
43-
},
44-
});
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import type {MultipleWindowsStat} from '../../../types/api/consumer';
2+
import type {TopicStats} from '../../../types/api/topic';
3+
import {formatBytes} from '../../../utils';
4+
import {DAY_IN_SECONDS, HOUR_IN_SECONDS, MINUTE_IN_SECONDS} from '../../../utils/constants';
5+
6+
import {
7+
parseProtobufTimestampToMs,
8+
parseProtobufDurationToMs,
9+
formatDurationToShortTimeFormat,
10+
} from '../../../utils/timeParsers';
11+
12+
import {VerticalBars} from '../../VerticalBars/VerticalBars';
13+
14+
import {createInfoFormatter} from '../utils';
15+
16+
export const prepareBytesWritten = (data?: MultipleWindowsStat) => {
17+
return {
18+
per_minute:
19+
data && data.per_minute ? Math.floor(Number(data.per_minute) / MINUTE_IN_SECONDS) : 0,
20+
per_hour: data && data.per_hour ? Math.floor(Number(data.per_hour) / HOUR_IN_SECONDS) : 0,
21+
per_day: data && data.per_day ? Math.floor(Number(data.per_day) / DAY_IN_SECONDS) : 0,
22+
};
23+
};
24+
25+
export const formatTopicStats = createInfoFormatter<TopicStats>({
26+
values: {
27+
store_size_bytes: formatBytes,
28+
min_last_write_time: (value) => {
29+
if (!value) {
30+
return formatDurationToShortTimeFormat(0);
31+
}
32+
33+
const durationMs = Date.now() - parseProtobufTimestampToMs(value);
34+
35+
// Duration could be negative because of the difference between server and local time
36+
// Usually it below 100ms, so it could be omitted
37+
return formatDurationToShortTimeFormat(durationMs < 0 ? 0 : durationMs);
38+
},
39+
max_write_time_lag: (value) =>
40+
formatDurationToShortTimeFormat(value ? parseProtobufDurationToMs(value) : 0),
41+
bytes_written: (value) =>
42+
value && <VerticalBars values={Object.values(prepareBytesWritten(value))} />,
43+
},
44+
labels: {
45+
store_size_bytes: 'Store size',
46+
min_last_write_time: 'Partitions max time since last write',
47+
max_write_time_lag: 'Partitions max write time lag',
48+
bytes_written: 'Average write speed',
49+
},
50+
});

src/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
export * from './CDCStreamInfo';
21
export * from './TableIndexInfo';
3-
export * from './PersQueueGroupInfo';

0 commit comments

Comments
 (0)