Преглед изворни кода

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>
soffest пре 4 година
родитељ
комит
4ec0422357

+ 20 - 2
kafka-ui-react-app/src/components/Brokers/Brokers.tsx

@@ -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;

+ 1 - 0
kafka-ui-react-app/src/components/Brokers/BrokersContainer.ts

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

+ 7 - 0
kafka-ui-react-app/src/components/Topics/Details/Overview/Overview.tsx

@@ -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">

+ 22 - 0
kafka-ui-react-app/src/components/common/BytesFormatted/BytesFormatted.tsx

@@ -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;

+ 4 - 2
kafka-ui-react-app/src/components/common/Dashboard/Indicator.tsx

@@ -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>

+ 5 - 1
kafka-ui-react-app/src/components/common/Dashboard/MetricsWrapper.tsx

@@ -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>
   );
 };

+ 5 - 0
kafka-ui-react-app/src/redux/reducers/brokers/selectors.ts

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

+ 10 - 0
kafka-ui-react-app/src/theme/bulma_overrides.scss

@@ -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;
+  }
+}