Brokers, Topic details: Display disk usage. (#129)

* Display brokers disk usage.

* Fixed disk usage alignment.

* Added disk usage to topic details.

* Updated metrics wrapper props.

Co-authored-by: Sofia Shnaidman <sshnaidman@provectus.com>
This commit is contained in:
soffest 2020-11-30 15:48:08 +03:00 committed by GitHub
parent 1a7aed10b6
commit 4ec0422357
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 5 deletions

View file

@ -6,6 +6,7 @@ import cx from 'classnames';
import MetricsWrapper from 'components/common/Dashboard/MetricsWrapper';
import Indicator from 'components/common/Dashboard/Indicator';
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
interface Props extends ClusterStats {
clusterName: ClusterName;
@ -14,7 +15,7 @@ interface Props extends ClusterStats {
fetchBrokers: (clusterName: ClusterName) => void;
}
const Topics: React.FC<Props> = ({
const Brokers: React.FC<Props> = ({
clusterName,
brokerCount,
activeControllers,
@ -24,6 +25,7 @@ const Topics: React.FC<Props> = ({
inSyncReplicasCount,
outOfSyncReplicasCount,
underReplicatedPartitionCount,
diskUsage,
fetchClusterStats,
fetchBrokers,
}) => {
@ -73,8 +75,24 @@ const Topics: React.FC<Props> = ({
{outOfSyncReplicasCount}
</Indicator>
</MetricsWrapper>
<MetricsWrapper multiline title="Disk Usage">
{diskUsage?.map((brokerDiskUsage) => (
<React.Fragment key={brokerDiskUsage.brokerId}>
<Indicator className="is-one-third" label="Broker">
{brokerDiskUsage.brokerId}
</Indicator>
<Indicator className="is-one-third" label="Segment Size" title="">
<BytesFormatted value={brokerDiskUsage.segmentSize} />
</Indicator>
<Indicator className="is-one-third" label="Segment count">
{brokerDiskUsage.segmentCount}
</Indicator>
</React.Fragment>
))}
</MetricsWrapper>
</div>
);
};
export default Topics;
export default Brokers;

View file

@ -31,6 +31,7 @@ const mapStateToProps = (
underReplicatedPartitionCount: brokerSelectors.getUnderReplicatedPartitionCount(
state
),
diskUsage: brokerSelectors.getDiskUsage(state),
});
const mapDispatchToProps = {

View file

@ -3,6 +3,7 @@ import { ClusterName, TopicName } from 'redux/interfaces';
import { Topic, TopicDetails } from 'generated-sources';
import MetricsWrapper from 'components/common/Dashboard/MetricsWrapper';
import Indicator from 'components/common/Dashboard/Indicator';
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
interface Props extends Topic, TopicDetails {
isFetched: boolean;
@ -22,6 +23,8 @@ const Overview: React.FC<Props> = ({
partitionCount,
internal,
replicationFactor,
segmentSize,
segmentCount,
fetchTopicDetails,
}) => {
React.useEffect(() => {
@ -53,6 +56,10 @@ const Overview: React.FC<Props> = ({
{internal ? 'Internal' : 'External'}
</span>
</Indicator>
<Indicator label="Segment Size" title="">
<BytesFormatted value={segmentSize} />
</Indicator>
<Indicator label="Segment count">{segmentCount}</Indicator>
</MetricsWrapper>
<div className="box">
<table className="table is-striped is-fullwidth">

View file

@ -0,0 +1,22 @@
import React from 'react';
interface Props {
value: string | number | undefined;
precision?: number;
}
const BytesFormatted: React.FC<Props> = ({ value, precision }) => {
const formatBytes = React.useCallback(() => {
const numVal = typeof value === 'string' ? parseInt(value, 10) : value;
if (!numVal) return 0;
const pow = Math.floor(Math.log2(numVal) / 10);
const multiplier = 10 ** (precision || 2);
return (
Math.round((numVal * multiplier) / 1024 ** pow) / multiplier +
['Bytes', 'KB', 'MB', 'GB', 'TB'][pow]
);
}, [value]);
return <span>{formatBytes()}</span>;
};
export default BytesFormatted;

View file

@ -1,13 +1,15 @@
import React from 'react';
import cx from 'classnames';
interface Props {
label: string;
title?: string;
className?: string;
}
const Indicator: React.FC<Props> = ({ label, title, children }) => {
const Indicator: React.FC<Props> = ({ label, title, className, children }) => {
return (
<div className="level-item level-left">
<div className={cx('level-item', 'level-left', className)}>
<div title={title || label}>
<p className="heading">{label}</p>
<p className="title">{children}</p>

View file

@ -4,17 +4,21 @@ import cx from 'classnames';
interface Props {
title?: string;
wrapperClassName?: string;
multiline?: boolean;
}
const MetricsWrapper: React.FC<Props> = ({
title,
children,
wrapperClassName,
multiline,
}) => {
return (
<div className={cx('box', wrapperClassName)}>
{title && <h5 className="subtitle is-6">{title}</h5>}
<div className="level">{children}</div>
<div className={cx('level', multiline ? 'level-multiline' : '')}>
{children}
</div>
</div>
);
};

View file

@ -43,3 +43,8 @@ export const getUnderReplicatedPartitionCount = createSelector(
brokersState,
({ underReplicatedPartitionCount }) => underReplicatedPartitionCount
);
export const getDiskUsage = createSelector(
brokersState,
({ diskUsage }) => diskUsage
);

View file

@ -68,3 +68,13 @@
from { opacity: 0; }
to { opacity: 1; }
}
.level.level-multiline {
flex-wrap: wrap;
.level-item.is-one-third {
flex-basis: 26%;
}
.level-item.is-one-third:nth-child(n+4) {
margin-top: 10px;
}
}