Fixed the processing to be done in backend now.
This commit is contained in:
1 parent
765a1a24ed
commit
f5d0b74ccf
5 files changed
+144
-80
No files matched your search
@@ -91,6 +91,49 @@ const getFormattedPercentage = (value) => {
|
||||
return `${(value * 100).toFixed(2)}%`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom tick component for rendering network bytes per second.
|
||||
*
|
||||
* @param {Object} props - The properties object.
|
||||
* @param {number} props.x - The x-coordinate for the tick.
|
||||
* @param {number} props.y - The y-coordinate for the tick.
|
||||
* @param {Object} props.payload - The payload object containing tick data.
|
||||
* @param {number} props.index - The index of the tick.
|
||||
* @returns {JSX.Element|null} The rendered tick component or null for the first tick.
|
||||
*/
|
||||
export const NetworkTick = ({ x, y, payload, index }) => {
|
||||
const theme = useTheme();
|
||||
if (index === 0) return null;
|
||||
|
||||
const formatBytes = (bytes) => {
|
||||
if (bytes >= 1_000_000_000) return `${(bytes / 1_000_000_000).toFixed(1)} GB/s`;
|
||||
if (bytes >= 1_000_000) return `${(bytes / 1_000_000).toFixed(1)} MB/s`;
|
||||
if (bytes >= 1_000) return `${(bytes / 1_000).toFixed(1)} KB/s`;
|
||||
return `${bytes} B/s`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Text
|
||||
x={x - 20}
|
||||
y={y}
|
||||
textAnchor="middle"
|
||||
fill={theme.palette.primary.contrastTextTertiary}
|
||||
fontSize={11}
|
||||
fontWeight={400}
|
||||
>
|
||||
{formatBytes(payload?.value)}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
NetworkTick.propTypes = {
|
||||
x: PropTypes.number,
|
||||
y: PropTypes.number,
|
||||
payload: PropTypes.object,
|
||||
index: PropTypes.number,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Custom tooltip component for displaying infrastructure data.
|
||||
*
|
||||
|
||||
@@ -7,6 +7,7 @@ import InfraAreaChart from "../../../../../Pages/Infrastructure/Details/Componen
|
||||
import {
|
||||
TzTick,
|
||||
InfrastructureTooltip,
|
||||
NetworkTick,
|
||||
} from "../../../../../Components/Charts/Utils/chartUtils";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -23,6 +24,7 @@ const NetworkCharts = ({ eth0Data, dateRange }) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
||||
const configs = [
|
||||
{
|
||||
type: "network-bytes",
|
||||
@@ -33,6 +35,7 @@ const NetworkCharts = ({ eth0Data, dateRange }) => {
|
||||
gradientStartColor: theme.palette.info.main,
|
||||
yLabel: t("bytesPerSecond"),
|
||||
xTick: <TzTick dateRange={dateRange} />,
|
||||
yTick: <NetworkTick />,
|
||||
toolTip: (
|
||||
<InfrastructureTooltip
|
||||
dotColor={theme.palette.info.main}
|
||||
|
||||
@@ -4,23 +4,32 @@ import NetworkCharts from "./NetworkCharts";
|
||||
import MonitorTimeFrameHeader from "../../../../../Components/MonitorTimeFrameHeader";
|
||||
|
||||
const Network = ({ net, checks, isLoading, dateRange, setDateRange }) => {
|
||||
const eth0Data = getEth0TimeSeries(checks);
|
||||
const eth0Data = (checks || [])
|
||||
.map((check) => {
|
||||
const en0 = (check.net || []).find((iface) => iface.name === "en0");
|
||||
if (!en0) return null;
|
||||
|
||||
return {
|
||||
_id: check._id,
|
||||
bytesPerSec: en0.avgBytesRecv,
|
||||
packetsPerSec: en0.avgPacketsRecv,
|
||||
errors: (en0.avgErrOut ?? 0),
|
||||
drops: (en0.avgDropOut ?? 0)
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
console.log(eth0Data);
|
||||
|
||||
return (
|
||||
<>
|
||||
<NetworkStatBoxes
|
||||
shouldRender={!isLoading}
|
||||
net={net}
|
||||
/>
|
||||
<NetworkStatBoxes shouldRender={!isLoading} net={net} />
|
||||
<MonitorTimeFrameHeader
|
||||
isLoading={isLoading}
|
||||
dateRange={dateRange}
|
||||
setDateRange={setDateRange}
|
||||
/>
|
||||
<NetworkCharts
|
||||
eth0Data={eth0Data}
|
||||
dateRange={dateRange}
|
||||
/>
|
||||
<NetworkCharts eth0Data={eth0Data} dateRange={dateRange} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -34,65 +43,3 @@ Network.propTypes = {
|
||||
};
|
||||
|
||||
export default Network;
|
||||
|
||||
/* ---------- Helper functions ---------- */
|
||||
function getEth0TimeSeries(checks) {
|
||||
const sorted = [...(checks || [])].sort((a, b) => new Date(a._id) - new Date(b._id));
|
||||
const series = [];
|
||||
let prev = null;
|
||||
|
||||
for (const check of sorted) {
|
||||
const eth = (check.net || []).find((iface) => iface.name === "en0");
|
||||
if (!eth) {
|
||||
prev = check;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
const prevEth = (prev.net || []).find((iface) => iface.name === "en0");
|
||||
const t1 = new Date(check._id);
|
||||
const t0 = new Date(prev._id);
|
||||
|
||||
if (!prevEth || isNaN(t1) || isNaN(t0)) {
|
||||
prev = check;
|
||||
continue;
|
||||
}
|
||||
|
||||
const dt = (t1 - t0) / 1000;
|
||||
|
||||
if (dt > 0) {
|
||||
const bytesField = eth.avgBytesSent;
|
||||
const prevBytesField = prevEth.avgBytesSent;
|
||||
|
||||
if (bytesField !== undefined && prevBytesField !== undefined) {
|
||||
const dataPoint = {
|
||||
_id: check._id,
|
||||
bytesPerSec: (bytesField - prevBytesField) / dt,
|
||||
packetsPerSec: (eth.avgPacketsSent - prevEth.avgPacketsSent) / dt,
|
||||
errors: (eth.avgErrIn ?? 0) + (eth.avgErrOut ?? 0),
|
||||
drops: 0,
|
||||
};
|
||||
series.push(dataPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = check;
|
||||
}
|
||||
|
||||
// If we only have one check, create a single data point with absolute values
|
||||
if (series.length === 0 && sorted.length === 1) {
|
||||
const check = sorted[0];
|
||||
const eth = (check.net || []).find((iface) => iface.name === "en0");
|
||||
if (eth) {
|
||||
series.push({
|
||||
_id: check._id,
|
||||
bytesPerSec: eth.avgBytesSent || 0,
|
||||
packetsPerSec: eth.avgPacketsSent || 0,
|
||||
errors: (eth.avgErrIn ?? 0) + (eth.avgErrOut ?? 0),
|
||||
drops: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return series;
|
||||
}
|
||||
Reference in new issue
Block a user