mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-07 02:09:46 -06:00
Added a drop down so that we have choice to make about which network interface to choose.
This commit is contained in:
@@ -109,7 +109,7 @@ export const NetworkTick = ({ x, y, payload, index, formatter }) => {
|
||||
formatter = (value, space = false) => {
|
||||
if (typeof value !== "number") return value;
|
||||
// need to add space between value and unit
|
||||
return `${(value / 1024).toFixed(2)}${space ? " " : ""}Kbps`;
|
||||
return `${(value / 1024).toFixed(1)}${space ? " " : ""}Kbps`;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { formatBytesString } = useHardwareUtils();
|
||||
const { formatBytesPerSecondString, formatPacketsPerSecondString } = useHardwareUtils();
|
||||
|
||||
if (!ethernetData?.length) {
|
||||
return <Typography>{t("noNetworkStatsAvailable")}</Typography>;
|
||||
@@ -26,19 +26,19 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
type: "network-bytes",
|
||||
data: ethernetData,
|
||||
dataKeys: ["bytesPerSec"],
|
||||
heading: t("bytesPerSecond"),
|
||||
heading: t("dataReceived"),
|
||||
strokeColor: theme.palette.info.main,
|
||||
gradientStartColor: theme.palette.info.main,
|
||||
yLabel: t("bytesPerSecond"),
|
||||
yLabel: t("rate"),
|
||||
xTick: <TzTick dateRange={dateRange} />,
|
||||
yTick: <NetworkTick formatter={formatBytesString} />,
|
||||
yTick: <NetworkTick formatter={formatBytesPerSecondString} />,
|
||||
toolTip: (
|
||||
<InfrastructureTooltip
|
||||
dotColor={theme.palette.info.main}
|
||||
yKey={"bytesPerSec"}
|
||||
yLabel={t("bytesPerSecond")}
|
||||
yLabel={t("dataRate") + ": "}
|
||||
dateRange={dateRange}
|
||||
formatter={formatBytesString}
|
||||
formatter={formatBytesPerSecondString}
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -46,18 +46,19 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
type: "network-packets",
|
||||
data: ethernetData,
|
||||
dataKeys: ["packetsPerSec"],
|
||||
heading: t("packetsPerSecond"),
|
||||
heading: t("packetsReceivedRate"),
|
||||
strokeColor: theme.palette.success.main,
|
||||
gradientStartColor: theme.palette.success.main,
|
||||
yLabel: t("packetsPerSecond"),
|
||||
yLabel: t("rate"),
|
||||
xTick: <TzTick dateRange={dateRange} />,
|
||||
yTick: <NetworkTick formatter={formatPacketsPerSecondString} />,
|
||||
toolTip: (
|
||||
<InfrastructureTooltip
|
||||
dotColor={theme.palette.success.main}
|
||||
yKey={"packetsPerSec"}
|
||||
yLabel={t("packetsPerSecond")}
|
||||
yLabel={t("packetsPerSecond") + ": "}
|
||||
dateRange={dateRange}
|
||||
formatter={(value) => Math.round(value).toLocaleString()}
|
||||
formatter={formatPacketsPerSecondString}
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -65,7 +66,7 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
type: "network-errors",
|
||||
data: ethernetData,
|
||||
dataKeys: ["errors"],
|
||||
heading: t("errors"),
|
||||
heading: t("networkErrors"),
|
||||
strokeColor: theme.palette.error.main,
|
||||
gradientStartColor: theme.palette.error.main,
|
||||
yLabel: t("errors"),
|
||||
@@ -74,7 +75,7 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
<InfrastructureTooltip
|
||||
dotColor={theme.palette.error.main}
|
||||
yKey={"errors"}
|
||||
yLabel={t("errors")}
|
||||
yLabel={t("errors") + ": "}
|
||||
dateRange={dateRange}
|
||||
formatter={(value) => Math.round(value).toLocaleString()}
|
||||
/>
|
||||
@@ -84,7 +85,7 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
type: "network-drops",
|
||||
data: ethernetData,
|
||||
dataKeys: ["drops"],
|
||||
heading: t("drops"),
|
||||
heading: t("networkDrops"),
|
||||
strokeColor: theme.palette.warning.main,
|
||||
gradientStartColor: theme.palette.warning.main,
|
||||
yLabel: t("drops"),
|
||||
@@ -93,7 +94,7 @@ const NetworkCharts = ({ ethernetData, dateRange }) => {
|
||||
<InfrastructureTooltip
|
||||
dotColor={theme.palette.warning.main}
|
||||
yKey={"drops"}
|
||||
yLabel={t("drops")}
|
||||
yLabel={t("drops") + ": "}
|
||||
dateRange={dateRange}
|
||||
formatter={(value) => Math.round(value).toLocaleString()}
|
||||
/>
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { useState, useEffect } from "react";
|
||||
import { FormControl, InputLabel, Select, MenuItem, Box } from "@mui/material";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import NetworkStatBoxes from "./NetworkStatBoxes";
|
||||
import NetworkCharts from "./NetworkCharts";
|
||||
import MonitorTimeFrameHeader from "../../../../../Components/MonitorTimeFrameHeader";
|
||||
|
||||
const getInterfaceName = (net) => {
|
||||
const interfaceNames = ["eth0", "Ethernet", "en0"];
|
||||
const found = (net || []).find((iface) => interfaceNames.includes(iface.name));
|
||||
return found ? found.name : null;
|
||||
const getAvailableInterfaces = (net) => {
|
||||
return (net || []).map((iface) => iface.name).filter(Boolean);
|
||||
};
|
||||
|
||||
const getNetworkInterfaceData = (checks, ifaceName) => {
|
||||
if (!ifaceName) return [];
|
||||
|
||||
// Transform backend data structure for the selected interface
|
||||
// Backend already calculates deltas, we just reshape the data
|
||||
return (checks || [])
|
||||
.map((check) => {
|
||||
const networkInterface = (check.net || []).find(
|
||||
@@ -28,21 +34,63 @@ const getNetworkInterfaceData = (checks, ifaceName) => {
|
||||
};
|
||||
|
||||
const Network = ({ net, checks, isLoading, dateRange, setDateRange }) => {
|
||||
const ifaceName = getInterfaceName(net);
|
||||
const ethernetData = getNetworkInterfaceData(checks, ifaceName);
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
const availableInterfaces = getAvailableInterfaces(net);
|
||||
const [selectedInterface, setSelectedInterface] = useState("");
|
||||
|
||||
// Set default interface when data loads
|
||||
useEffect(() => {
|
||||
if (availableInterfaces.length > 0 && !selectedInterface) {
|
||||
setSelectedInterface(availableInterfaces[0]);
|
||||
}
|
||||
}, [availableInterfaces, selectedInterface]);
|
||||
|
||||
const ethernetData = getNetworkInterfaceData(checks, selectedInterface);
|
||||
|
||||
return (
|
||||
<>
|
||||
<NetworkStatBoxes
|
||||
shouldRender={!isLoading}
|
||||
net={net}
|
||||
ifaceName={ifaceName}
|
||||
/>
|
||||
<MonitorTimeFrameHeader
|
||||
isLoading={isLoading}
|
||||
dateRange={dateRange}
|
||||
setDateRange={setDateRange}
|
||||
ifaceName={selectedInterface}
|
||||
/>
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="flex-end"
|
||||
gap={theme.spacing(4)}
|
||||
>
|
||||
{availableInterfaces.length > 0 && (
|
||||
<FormControl
|
||||
variant="outlined"
|
||||
size="small"
|
||||
sx={{ minWidth: 200 }}
|
||||
>
|
||||
<InputLabel>{t("networkInterface")}</InputLabel>
|
||||
<Select
|
||||
value={selectedInterface}
|
||||
onChange={(e) => setSelectedInterface(e.target.value)}
|
||||
label={t("networkInterface")}
|
||||
>
|
||||
{availableInterfaces.map((interfaceName) => (
|
||||
<MenuItem
|
||||
key={interfaceName}
|
||||
value={interfaceName}
|
||||
>
|
||||
{interfaceName}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
<MonitorTimeFrameHeader
|
||||
isLoading={isLoading}
|
||||
dateRange={dateRange}
|
||||
setDateRange={setDateRange}
|
||||
/>
|
||||
</Box>
|
||||
<NetworkCharts
|
||||
ethernetData={ethernetData}
|
||||
dateRange={dateRange}
|
||||
|
||||
@@ -73,23 +73,50 @@ const useHardwareUtils = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const formatBytesString = (bytes, space = false) => {
|
||||
const formatBytesPerSecondString = (bytesPerSec, space = false) => {
|
||||
if (
|
||||
bytes === undefined ||
|
||||
bytes === null ||
|
||||
typeof bytes !== "number" ||
|
||||
bytes === 0
|
||||
bytesPerSec === undefined ||
|
||||
bytesPerSec === null ||
|
||||
typeof bytesPerSec !== "number" ||
|
||||
bytesPerSec === 0
|
||||
) {
|
||||
return `0${space ? " " : ""}${t("gb")}`;
|
||||
return `0${space ? " " : ""}B/s`;
|
||||
}
|
||||
|
||||
const GB = bytes / (1024 * 1024 * 1024);
|
||||
const MB = bytes / (1024 * 1024);
|
||||
const GB = bytesPerSec / (1024 * 1024 * 1024);
|
||||
const MB = bytesPerSec / (1024 * 1024);
|
||||
const KB = bytesPerSec / 1024;
|
||||
|
||||
if (GB >= 1) {
|
||||
return `${Number(GB.toFixed(2))}${space ? " " : ""}${t("gb")}`;
|
||||
return `${Number(GB.toFixed(1))}${space ? " " : ""}GB/s`;
|
||||
} else if (MB >= 1) {
|
||||
return `${Number(MB.toFixed(1))}${space ? " " : ""}MB/s`;
|
||||
} else if (KB >= 1) {
|
||||
return `${Number(KB.toFixed(1))}${space ? " " : ""}KB/s`;
|
||||
} else {
|
||||
return `${Number(MB.toFixed(2))}${space ? " " : ""}${t("mb")}`;
|
||||
return `${Number(bytesPerSec.toFixed(1))}${space ? " " : ""}B/s`;
|
||||
}
|
||||
};
|
||||
|
||||
const formatPacketsPerSecondString = (packetsPerSec, space = false) => {
|
||||
if (
|
||||
packetsPerSec === undefined ||
|
||||
packetsPerSec === null ||
|
||||
typeof packetsPerSec !== "number" ||
|
||||
packetsPerSec === 0
|
||||
) {
|
||||
return `0${space ? " " : ""}pps`;
|
||||
}
|
||||
|
||||
const M = packetsPerSec / (1000 * 1000);
|
||||
const K = packetsPerSec / 1000;
|
||||
|
||||
if (M >= 1) {
|
||||
return `${Number(M.toFixed(1))}${space ? " " : ""}Mpps`;
|
||||
} else if (K >= 1) {
|
||||
return `${Number(K.toFixed(1))}${space ? " " : ""}Kpps`;
|
||||
} else {
|
||||
return `${Math.round(packetsPerSec)}${space ? " " : ""}pps`;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,7 +181,8 @@ const useHardwareUtils = () => {
|
||||
decimalToPercentage,
|
||||
buildTemps,
|
||||
getDimensions,
|
||||
formatBytesString,
|
||||
formatBytesPerSecondString,
|
||||
formatPacketsPerSecondString,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -205,6 +205,10 @@
|
||||
"bytesPerSecond": "Bytes per second",
|
||||
"bytesReceived": "Bytes Received",
|
||||
"bytesSent": "Bytes Sent",
|
||||
"dataReceived": "Data Received",
|
||||
"dataSent": "Data Sent",
|
||||
"dataRate": "Data Rate",
|
||||
"rate": "Rate",
|
||||
"bulkImport": {
|
||||
"fallbackPage": "Import a file to upload a list of servers in bulk",
|
||||
"invalidFileType": "Invalid file type",
|
||||
@@ -341,6 +345,10 @@
|
||||
"errors": "Errors",
|
||||
"errorsIn": "Errors In",
|
||||
"errorsOut": "Errors Out",
|
||||
"networkErrors": "Network Errors",
|
||||
"networkDrops": "Network Drops",
|
||||
"networkInterface": "Network Interface",
|
||||
"selectInterface": "Select Interface",
|
||||
"details": "Details",
|
||||
"displayName": "Display name",
|
||||
"distributedRightCategoryTitle": "Monitor",
|
||||
@@ -763,6 +771,7 @@
|
||||
},
|
||||
"packetsPerSecond": "Packets per second",
|
||||
"packetsReceived": "Packets Received",
|
||||
"packetsReceivedRate": "Packets Received Rate",
|
||||
"packetsSent": "Packets Sent",
|
||||
"pause": "Pause",
|
||||
"pingMonitoring": "Ping monitoring",
|
||||
|
||||
Reference in New Issue
Block a user