From c5bb205d88a6ee4febaf958e48f4999ddb9f05ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Fri, 3 Feb 2023 14:12:44 +0100 Subject: [PATCH] feat: aggregate by label and type (#3047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About the changes We noticed in our instance that when we have the same label for different API types, it shows duplicated in the overview: ![image](https://user-images.githubusercontent.com/455064/216580261-91b09446-9f96-430f-8373-6a9dc7a3e623.png) We're changing to this way of displaying info: ![Screenshot from 2023-02-03 11-35-26](https://user-images.githubusercontent.com/455064/216580027-ada82e24-a3f3-4985-acef-4754e6177b13.png) when the data in traffic looks like this: ![Screenshot from 2023-02-03 11-35-35](https://user-images.githubusercontent.com/455064/216580065-0125f792-24af-4a96-bce6-584b70c7efbb.png) --------- Co-authored-by: Nuno Góis --- .../NetworkOverview/NetworkOverview.tsx | 59 ++++++++++++------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/frontend/src/component/admin/network/NetworkOverview/NetworkOverview.tsx b/frontend/src/component/admin/network/NetworkOverview/NetworkOverview.tsx index 424fd8327c..5ab03951f8 100644 --- a/frontend/src/component/admin/network/NetworkOverview/NetworkOverview.tsx +++ b/frontend/src/component/admin/network/NetworkOverview/NetworkOverview.tsx @@ -5,7 +5,10 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit import { Alert, styled } from '@mui/material'; import { unknownify } from 'utils/unknownify'; import { useMemo } from 'react'; -import { RequestsPerSecondSchema } from 'openapi'; +import { + RequestsPerSecondSchema, + RequestsPerSecondSchemaDataResultItem, +} from 'openapi'; import logoIcon from 'assets/icons/logoBg.svg'; import { formatAssetPath } from 'utils/formatPath'; @@ -24,29 +27,45 @@ const isRecent = (value: ResultValue) => { type ResultValue = [number, string]; interface INetworkApp { - label?: string; - reqs: string; + label: string; + reqs: number; type: string; } +const asNetworkAppData = (result: RequestsPerSecondSchemaDataResultItem) => { + const values = (result.values || []) as ResultValue[]; + const data = values.filter(value => isRecent(value)); + const reqs = data.length ? parseFloat(data[data.length - 1][1]) : 0; + return { + label: unknownify(result.metric?.appName), + reqs, + type: unknownify(result.metric?.endpoint?.split('/')[2]), + }; +}; + +const summingReqsByLabelAndType = ( + acc: { + [group: string]: INetworkApp; + }, + current: INetworkApp +) => { + const groupBy = current.label + current.type; + acc[groupBy] = { + ...current, + reqs: current.reqs + (acc[groupBy]?.reqs ?? 0), + }; + return acc; +}; + const toGraphData = (metrics?: RequestsPerSecondSchema) => { - const results = metrics?.data?.result; + const results = + metrics?.data?.result?.filter(result => result.metric?.appName) || []; + const aggregated = results + .map(asNetworkAppData) + .reduce(summingReqsByLabelAndType, {}); return ( - results - ?.map(result => { - const values = (result.values || []) as ResultValue[]; - const data = values.filter(value => isRecent(value)) || []; - let reqs = 0; - if (data.length) { - reqs = parseFloat(data[data.length - 1][1]); - } - return { - label: unknownify(result.metric?.appName), - reqs: reqs.toFixed(2), - type: unknownify(result.metric?.endpoint?.split('/')[2]), - }; - }) - .filter(app => app.label !== 'unknown') + Object.values(aggregated) + .map(app => ({ ...app, reqs: app.reqs.toFixed(2) })) .filter(app => app.reqs !== '0.00') ?? [] ); }; @@ -54,7 +73,7 @@ const toGraphData = (metrics?: RequestsPerSecondSchema) => { export const NetworkOverview = () => { usePageTitle('Network - Overview'); const { metrics } = useInstanceMetrics(); - const apps: INetworkApp[] = useMemo(() => { + const apps = useMemo(() => { return toGraphData(metrics); }, [metrics]);