components/metrics/MetricsTable.tsx (270 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import { Text, Table, TableContainer, Tbody, Th, Thead, Tr, Td, Box, } from '@chakra-ui/react'; import axios from 'axios'; import React, { useContext, useEffect, useState } from 'react'; import { AppContext } from '../../context/context'; interface EventMeshMetrics { maxHTTPTPS: number, avgHTTPTPS: number, maxHTTPCost: number, avgHTTPCost: number, avgHTTPBodyDecodeCost: number, httpDiscard: number, maxBatchSendMsgTPS: number, avgBatchSendMsgTPS: number, sendBatchMsgNumSum: number, sendBatchMsgFailNumSum: number, sendBatchMsgFailRate: number, sendBatchMsgDiscardNumSum: number, maxSendMsgTPS: number, avgSendMsgTPS: number, sendMsgNumSum: number, sendMsgFailNumSum: number, sendMsgFailRate: number, replyMsgNumSum: number, replyMsgFailNumSum: number, maxPushMsgTPS: number, avgPushMsgTPS: number, pushHTTPMsgNumSum: number, pushHTTPMsgFailNumSum: number, pushHTTPMsgFailRate: number, maxHTTPPushLatency : number, avgHTTPPushLatency : number, batchMsgQueueSize : number, sendMsgQueueSize : number, pushMsgQueueSize : number, retryHTTPQueueSize : number, avgBatchSendMsgCost : number, avgSendMsgCost : number, avgReplyMsgCost : number, // TCP Metrics retryTCPQueueSize: number, client2eventMeshTCPTPS : number, eventMesh2mqTCPTPS : number, mq2eventMeshTCPTPS : number, eventMesh2clientTCPTPS : number, allTCPTPS : number, allTCPConnections : number, subTopicTCPNum : number } const MetricsTable = () => { const { state } = useContext(AppContext); const [metrics, setMetrics] = useState<Partial<EventMeshMetrics>>({}); useEffect(() => { const fetch = async () => { try { const { data } = await axios.get<EventMeshMetrics>(`${state.endpoint}/metrics`); setMetrics(data); } catch (error) { setMetrics({}); } }; fetch(); }, []); type MetricRecord = Record<string, number | undefined>; const httpMetrics: MetricRecord = { 'Max HTTP TPS': metrics.maxHTTPTPS, 'Avg HTTP TPS': metrics.avgHTTPTPS, 'Max HTTP Cost': metrics.maxHTTPCost, 'Avg HTTP Cost': metrics.avgHTTPCost, 'Avg HTTP Body Decode Cost': metrics.avgHTTPBodyDecodeCost, 'HTTP Discard': metrics.httpDiscard, }; const batchMetrics: MetricRecord = { 'Max Batch Send Msg TPS': metrics.maxBatchSendMsgTPS, 'Avg Batch Send Msg TPS': metrics.avgBatchSendMsgTPS, 'Send Batch Msg Num Sum': metrics.sendBatchMsgNumSum, 'Send Batch Msg Fail Num Sum': metrics.sendBatchMsgFailNumSum, 'Send Batch Msg Fail Rate': metrics.sendBatchMsgFailRate, 'Send Batch Msg Discard Num Sum': metrics.sendBatchMsgDiscardNumSum, }; const sendMetrics: MetricRecord = { 'Max Send Msg TPS': metrics.maxSendMsgTPS, 'Avg Send Msg TPS': metrics.avgSendMsgTPS, 'Send Msg Num Sum': metrics.sendMsgNumSum, 'Send Msg Fail Num Sum': metrics.sendMsgFailNumSum, 'Send Msg Fail Rate': metrics.sendMsgFailRate, 'Reply Msg Num Sum': metrics.replyMsgNumSum, 'Reply Msg Fail Num Sum': metrics.replyMsgFailNumSum, }; const pushMetrics: MetricRecord = { 'Max Push Msg TPS': metrics.maxPushMsgTPS, 'Avg Push Msg TPS': metrics.avgPushMsgTPS, 'Push HTTP Msg Num Sum': metrics.pushHTTPMsgNumSum, 'Push HTTP Msg Fail Num Sum': metrics.pushHTTPMsgFailNumSum, 'Push HTTP Msg Fail Rate': metrics.pushHTTPMsgFailRate, 'Max HTTP Push Latency': metrics.maxHTTPPushLatency, 'Avg HTTP Push Latency': metrics.avgHTTPPushLatency, }; const tcpMetrics: MetricRecord = { 'Retry TCP Queue Size': metrics.retryTCPQueueSize, 'Client2eventMesh TCP TPS': metrics.client2eventMeshTCPTPS, 'EventMesh2mq TCP TPS': metrics.eventMesh2mqTCPTPS, 'MQ2eventMesh TCP TPS': metrics.mq2eventMeshTCPTPS, 'EventMesh2client TCP TPS': metrics.eventMesh2clientTCPTPS, 'All TCP TPS': metrics.allTCPTPS, 'All TCP Connections': metrics.allTCPConnections, 'Sub Topic TCP Num': metrics.subTopicTCPNum, }; const convertConfigurationToTable = ( metricRecord: Record<string, string | number | boolean | undefined>, ) => Object.entries(metricRecord).map(([key, value]) => { if (value === undefined) { return ( <Tr> <Td>{key}</Td> <Td>Undefined</Td> </Tr> ); } return ( <Tr> <Td>{key}</Td> <Td>{value.toString()}</Td> </Tr> ); }); if (Object.keys(metrics).length === 0) { return ( <Box maxW="full" bg="white" borderWidth="2px" borderRadius="md" borderColor="rgb(211,85,25)" overflow="hidden" p="4" mt="4" opacity="0.8" > <Text fontSize="l" fontWeight="semibold" color="rgb(211,85,25)" textAlign={['left', 'center']}> EventMesh Daemon Not Connected </Text> </Box> ); } return ( <> <Box maxW="full" bg="white" borderWidth="1px" borderRadius="md" overflow="hidden" p="4" mt="4" > <Text w="full" > EventMesh HTTP Metrics </Text> <TableContainer mt="4"> <Table variant="simple"> <Thead> <Tr> <Th>Metric</Th> <Th>Value</Th> </Tr> </Thead> <Tbody> {convertConfigurationToTable(httpMetrics)} </Tbody> </Table> </TableContainer> <Text w="full" mt="4" > HTTP Batch Metrics </Text> <TableContainer mt="4"> <Table variant="simple"> <Thead> <Tr> <Th>Metric</Th> <Th>Value</Th> </Tr> </Thead> <Tbody> {convertConfigurationToTable(batchMetrics)} </Tbody> </Table> </TableContainer> <Text w="full" mt="4" > HTTP Send Metrics </Text> <TableContainer mt="4"> <Table variant="simple"> <Thead> <Tr> <Th>Metric</Th> <Th>Value</Th> </Tr> </Thead> <Tbody> {convertConfigurationToTable(sendMetrics)} </Tbody> </Table> </TableContainer> <Text w="full" mt="4" > HTTP Push Metrics </Text> <TableContainer mt="4"> <Table variant="simple"> <Thead> <Tr> <Th>Metric</Th> <Th>Value</Th> </Tr> </Thead> <Tbody> {convertConfigurationToTable(pushMetrics)} </Tbody> </Table> </TableContainer> </Box> <Box maxW="full" bg="white" borderWidth="1px" borderRadius="md" overflow="hidden" p="4" mt="4" > <Text w="full" mt="4" > TCP Metrics </Text> <TableContainer mt="4"> <Table variant="simple"> <Thead> <Tr> <Th>Metric</Th> <Th>Value</Th> </Tr> </Thead> <Tbody> {convertConfigurationToTable(tcpMetrics)} </Tbody> </Table> </TableContainer> </Box> </> ); }; export default MetricsTable;