diff --git a/frontend/src/components/Brokers/Brokers.tsx b/frontend/src/components/Brokers/Brokers.tsx index 552beac1da..5be1cee3e5 100644 --- a/frontend/src/components/Brokers/Brokers.tsx +++ b/frontend/src/components/Brokers/Brokers.tsx @@ -1,11 +1,15 @@ import React from 'react'; import PageLoader from 'components/common/PageLoader/PageLoader'; -import { ClusterId } from 'types'; +import { ClusterId, BrokerMetrics, ZooKeeperStatus } from 'types'; import useInterval from 'lib/hooks/useInterval'; +import formatBytes from 'lib/utils/formatBytes'; +import cx from 'classnames'; -interface Props { +interface Props extends BrokerMetrics { clusterId: string; isFetched: boolean; + minDiskUsage: number; + maxDiskUsage: number; fetchBrokers: (clusterId: ClusterId) => void; fetchBrokerMetrics: (clusterId: ClusterId) => void; } @@ -13,6 +17,17 @@ interface Props { const Topics: React.FC = ({ clusterId, isFetched, + brokerCount, + activeControllers, + zooKeeperStatus, + onlinePartitionCount, + offlinePartitionCount, + underReplicatedPartitionCount, + diskUsageDistribution, + minDiskUsage, + maxDiskUsage, + networkPoolUsage, + requestPoolUsage, fetchBrokers, fetchBrokerMetrics, }) => { @@ -27,8 +42,129 @@ const Topics: React.FC = ({ useInterval(() => { fetchBrokerMetrics(clusterId); }, 5000); if (isFetched) { + const [minDiskUsageValue, minDiskUsageSize] = formatBytes(minDiskUsage); + const [maxDiskUsageValue, maxDiskUsageSize] = formatBytes(maxDiskUsage); + return ( -
Brokers of {clusterId}
+
+
+
Uptime
+
+
+
+

Total Brokers

+

{brokerCount}

+
+
+
+
+

Active Controllers

+

{activeControllers}

+
+
+
+
+

Zookeeper Status

+

+ {zooKeeperStatus === ZooKeeperStatus.online ? ( + Online + ) : ( + Offline + )} +

+
+
+
+
+ +
+
Partitions
+
+
+
+

Online

+

+ + {onlinePartitionCount} + + of {onlinePartitionCount + offlinePartitionCount} +

+
+
+
+
+

Under Replicated

+

{underReplicatedPartitionCount}

+
+
+
+
+

In Sync Replicas

+

Soon

+
+
+
+
+

Out of Sync Replicas

+

Soon

+
+
+
+
+ +
+
Disk
+
+
+
+

Max usage

+

+ {maxDiskUsageValue} + {maxDiskUsageSize} +

+
+
+
+
+

Min Usage

+

+ {minDiskUsageValue} + {minDiskUsageSize} +

+
+
+
+
+

Distribution

+

{diskUsageDistribution}

+
+
+
+
+
+
System
+
+
+
+

Network pool usage

+

+ {Math.round(networkPoolUsage * 10000) / 100} + % +

+
+
+
+
+

Request pool usage

+

+ {Math.round(requestPoolUsage * 10000) / 100} + % +

+
+
+
+
+
); } diff --git a/frontend/src/components/Brokers/BrokersContainer.ts b/frontend/src/components/Brokers/BrokersContainer.ts index 213e76ac51..771977e629 100644 --- a/frontend/src/components/Brokers/BrokersContainer.ts +++ b/frontend/src/components/Brokers/BrokersContainer.ts @@ -4,7 +4,7 @@ import { fetchBrokerMetrics, } from 'redux/reducers/brokers/thunks'; import Brokers from './Brokers'; -import { getIsBrokerListFetched } from 'redux/reducers/brokers/selectors'; +import * as brokerSelectors from 'redux/reducers/brokers/selectors'; import { RootState, ClusterId } from 'types'; import { RouteComponentProps } from 'react-router-dom'; @@ -15,8 +15,19 @@ interface RouteProps { interface OwnProps extends RouteComponentProps { } const mapStateToProps = (state: RootState, { match: { params: { clusterId } }}: OwnProps) => ({ - isFetched: getIsBrokerListFetched(state), + isFetched: brokerSelectors.getIsBrokerListFetched(state), clusterId, + brokerCount: brokerSelectors.getBrokerCount(state), + zooKeeperStatus: brokerSelectors.getZooKeeperStatus(state), + activeControllers: brokerSelectors.getActiveControllers(state), + networkPoolUsage: brokerSelectors.getNetworkPoolUsage(state), + requestPoolUsage: brokerSelectors.getRequestPoolUsage(state), + onlinePartitionCount: brokerSelectors.getOnlinePartitionCount(state), + offlinePartitionCount: brokerSelectors.getOfflinePartitionCount(state), + underReplicatedPartitionCount: brokerSelectors.getUnderReplicatedPartitionCount(state), + diskUsageDistribution: brokerSelectors.getDiskUsageDistribution(state), + minDiskUsage: brokerSelectors.getMinDiskUsage(state), + maxDiskUsage: brokerSelectors.getMaxDiskUsage(state), }); const mapDispatchToProps = { diff --git a/frontend/src/components/Topics/List/List.tsx b/frontend/src/components/Topics/List/List.tsx index 96fefe5ef2..ab414ca00e 100644 --- a/frontend/src/components/Topics/List/List.tsx +++ b/frontend/src/components/Topics/List/List.tsx @@ -18,44 +18,42 @@ const List: React.FC = ({ const items = showInternal ? topics : externalTopics; return ( - <> -
-
-
- - -
-
-
- - - - - - - - - - {items.map((topic) => ( - - ))} - -
Topic NameTotal PartitionsOut of sync replicas
+
+
+
+ +
- +
+ + + + + + + + + + {items.map((topic) => ( + + ))} + +
Topic NameTotal PartitionsOut of sync replicas
+
+
); } diff --git a/frontend/src/lib/api/brokers.ts b/frontend/src/lib/api/brokers.ts index eb2aba2ade..417be6f8c7 100644 --- a/frontend/src/lib/api/brokers.ts +++ b/frontend/src/lib/api/brokers.ts @@ -8,7 +8,7 @@ import { BASE_PARAMS, } from 'lib/constants'; -export const getBrokers = (clusterId: ClusterId): Promise<{ brokers: Broker[] }> => +export const getBrokers = (clusterId: ClusterId): Promise => fetch(`${BASE_URL}/clusters/${clusterId}/brokers`, { ...BASE_PARAMS }) .then(res => res.json()); diff --git a/frontend/src/redux/reducers/brokers/reducer.ts b/frontend/src/redux/reducers/brokers/reducer.ts index f825b52a30..59537117c3 100644 --- a/frontend/src/redux/reducers/brokers/reducer.ts +++ b/frontend/src/redux/reducers/brokers/reducer.ts @@ -9,8 +9,8 @@ export const initialState: BrokersState = { networkPoolUsage: 0, requestPoolUsage: 0, onlinePartitionCount: 0, - underReplicatedPartitionCount: 0, offlinePartitionCount: 0, + underReplicatedPartitionCount: 0, diskUsageDistribution: undefined, }; diff --git a/frontend/src/redux/reducers/brokers/selectors.ts b/frontend/src/redux/reducers/brokers/selectors.ts index 907a9bb7b9..d5d37b304b 100644 --- a/frontend/src/redux/reducers/brokers/selectors.ts +++ b/frontend/src/redux/reducers/brokers/selectors.ts @@ -13,8 +13,22 @@ export const getIsBrokerListFetched = createSelector( const getBrokerList = createSelector(brokersState, ({ items }) => items); -export const getTotalBrokers = createSelector( - getIsBrokerListFetched, +export const getBrokerCount = createSelector(brokersState, ({ brokerCount }) => brokerCount); +export const getZooKeeperStatus = createSelector(brokersState, ({ zooKeeperStatus }) => zooKeeperStatus); +export const getActiveControllers = createSelector(brokersState, ({ activeControllers }) => activeControllers); +export const getNetworkPoolUsage = createSelector(brokersState, ({ networkPoolUsage }) => networkPoolUsage); +export const getRequestPoolUsage = createSelector(brokersState, ({ requestPoolUsage }) => requestPoolUsage); +export const getOnlinePartitionCount = createSelector(brokersState, ({ onlinePartitionCount }) => onlinePartitionCount); +export const getOfflinePartitionCount = createSelector(brokersState, ({ offlinePartitionCount }) => offlinePartitionCount); +export const getDiskUsageDistribution = createSelector(brokersState, ({ diskUsageDistribution }) => diskUsageDistribution); +export const getUnderReplicatedPartitionCount = createSelector(brokersState, ({ underReplicatedPartitionCount }) => underReplicatedPartitionCount); + +export const getMinDiskUsage = createSelector( getBrokerList, - (isFetched, brokers) => (isFetched && brokers !== undefined ? brokers.length : undefined), + (brokers) => Math.min(...brokers.map(({ segmentSize }) => segmentSize)), +); + +export const getMaxDiskUsage = createSelector( + getBrokerList, + (brokers) => Math.max(...brokers.map(({ segmentSize }) => segmentSize)), ); diff --git a/frontend/src/redux/reducers/brokers/thunks.ts b/frontend/src/redux/reducers/brokers/thunks.ts index 717dbf0fa4..082b55e5e4 100644 --- a/frontend/src/redux/reducers/brokers/thunks.ts +++ b/frontend/src/redux/reducers/brokers/thunks.ts @@ -9,8 +9,8 @@ import { PromiseThunk, ClusterId } from 'types'; export const fetchBrokers = (clusterId: ClusterId): PromiseThunk => async (dispatch) => { dispatch(fetchBrokersAction.request()); try { - const { brokers } = await getBrokers(clusterId); - dispatch(fetchBrokersAction.success(brokers)); + const payload = await getBrokers(clusterId); + dispatch(fetchBrokersAction.success(payload)); } catch (e) { dispatch(fetchBrokersAction.failure()); } diff --git a/frontend/src/types/broker.ts b/frontend/src/types/broker.ts index 19116805d9..673387d0e0 100644 --- a/frontend/src/types/broker.ts +++ b/frontend/src/types/broker.ts @@ -8,7 +8,7 @@ export interface Broker { bytesOutPerSec: number; }; -export enum ZooKeeperStatus { online, offline }; +export enum ZooKeeperStatus { offline, online }; export interface BrokerDiskUsage { brokerId: BrokerId; @@ -22,8 +22,8 @@ export interface BrokerMetrics { networkPoolUsage: number; requestPoolUsage: number; onlinePartitionCount: number; - underReplicatedPartitionCount: number; offlinePartitionCount: number; + underReplicatedPartitionCount: number; diskUsageDistribution?: string; }