diff --git a/client/src/Components/Charts/Utils/chartUtils.jsx b/client/src/Components/Charts/Utils/chartUtils.jsx
index ce15d27cd..e24881c1c 100644
--- a/client/src/Components/Charts/Utils/chartUtils.jsx
+++ b/client/src/Components/Charts/Utils/chartUtils.jsx
@@ -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`;
};
}
diff --git a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
index 98eced859..9157a3432 100644
--- a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
+++ b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
@@ -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 {t("noNetworkStatsAvailable")};
@@ -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: ,
- yTick: ,
+ yTick: ,
toolTip: (
),
},
@@ -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: ,
+ yTick: ,
toolTip: (
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 }) => {
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 }) => {
Math.round(value).toLocaleString()}
/>
diff --git a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
index 623720aba..227523439 100644
--- a/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
+++ b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
@@ -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 (
<>
-
+
+ {availableInterfaces.length > 0 && (
+
+ {t("networkInterface")}
+
+
+ )}
+
+
{
}
};
- 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,
};
};
diff --git a/client/src/locales/en.json b/client/src/locales/en.json
index 08c60c372..857825c9f 100644
--- a/client/src/locales/en.json
+++ b/client/src/locales/en.json
@@ -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",