feat: Added active and total for network usage (dw,up) resources.

upd: Docs updated for network usage.
add: Widget resorce iconChildren param added.
upd: config file default options added.
upd: resources units type added.
This commit is contained in:
Ramazan Sancar 2024-11-25 06:25:52 +03:00 committed by GitHub
parent a06964dd17
commit 15d2eaec02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 99 additions and 3 deletions

View File

@ -175,6 +175,7 @@ data:
expanded: true expanded: true
cpu: true cpu: true
memory: true memory: true
network: default
- search: - search:
provider: duckduckgo provider: duckduckgo
target: _blank target: _blank
@ -370,7 +371,7 @@ prevent unnecessary re-renders on page loads and window / tab focusing. The
procedure for enabling sticky sessions depends on your Ingress controller. Below procedure for enabling sticky sessions depends on your Ingress controller. Below
is an example using Traefik as the Ingress controller. is an example using Traefik as the Ingress controller.
``` ```yaml
apiVersion: traefik.io/v1alpha1 apiVersion: traefik.io/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:

View File

@ -20,11 +20,12 @@ _Note: unfortunately, the package used for getting CPU temp ([systeminformation]
cpu: true cpu: true
memory: true memory: true
disk: /disk/mount/path disk: /disk/mount/path
network: default # options: 'default' or active network interface name
cputemp: true cputemp: true
tempmin: 0 # optional, minimum cpu temp tempmin: 0 # optional, minimum cpu temp
tempmax: 100 # optional, maximum cpu temp tempmax: 100 # optional, maximum cpu temp
uptime: true uptime: true
units: imperial # only used by cpu temp units: imperial # only used by cpu temp widget, options: 'imperial' or 'metric'
refresh: 3000 # optional, in ms refresh: 3000 # optional, in ms
diskUnits: bytes # optional, bytes (default) or bbytes. Only applies to disk diskUnits: bytes # optional, bytes (default) or bbytes. Only applies to disk
``` ```

View File

@ -0,0 +1,62 @@
import useSWR from "swr";
import { FaNetworkWired, FaAngleUp, FaAngleDown } from "react-icons/fa";
import { useTranslation } from "next-i18next";
import Resource from "../widget/resource";
import Error from "../widget/error";
export default function Network({ options, refresh = 1500 }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/widgets/resources?type=network${(options.network || ( options.network !== 'default' && options.network === `false`)) ? `&interfaceName=${options.network}` : '' }`, {
refreshInterval: refresh,
});
if (error || data?.error) {
return <Error />;
}
if (!data) {
return (
<Resource
icon={FaNetworkWired}
value="-"
label={<FaAngleUp/>}
expandedValue="-"
expandedLabel={<FaAngleDown/>}
percentage="0"
expanded="true"
/>
);
}
return (
<>
/* Active Usage */
<Resource
icon={FaNetworkWired}
value={t('common.bits', { value: data?.network?.tx_sec })}
label={<FaAngleUp/>}
expandedValue={t('common.bits', { value: data?.network?.rx_sec })}
expandedLabel={<FaAngleDown/>}
percentage="0"
expanded="true"
children={<div className="pt-1 text-theme-800 dark:text-theme-200 text-xs text-center">{t('pyload.speed')}</div>}
iconChildren={<span class="bg-theme-100 text-theme-800 text-xs font-medium px-1 py-1 mt-1 rounded dark:bg-theme-700 dark:text-theme-300 text-center">{data.interface}</span>}
/>
/* Total Usage */
<Resource
icon={FaNetworkWired}
value={t('common.bbytes', { value: data?.network?.tx_bytes })}
label={<FaAngleUp/>}
expandedValue={t('common.bbytes', { value: data?.network?.rx_bytes })}
expandedLabel={<FaAngleDown/>}
percentage="0"
expanded="true"
children={<div className="pt-1 text-theme-800 dark:text-theme-200 text-xs text-center">{t('pyload.total')}</div>}
iconChildren={<span class="bg-theme-100 text-theme-800 text-xs font-medium px-1 py-1 mt-1 rounded dark:bg-theme-700 dark:text-theme-300 text-center">{data.interface}</span>}
/>
</>
);
}

View File

@ -6,6 +6,7 @@ import Cpu from "./cpu";
import Memory from "./memory"; import Memory from "./memory";
import CpuTemp from "./cputemp"; import CpuTemp from "./cputemp";
import Uptime from "./uptime"; import Uptime from "./uptime";
import Network from "./network";
export default function Resources({ options }) { export default function Resources({ options }) {
const { expanded, units, diskUnits, tempmin, tempmax } = options; const { expanded, units, diskUnits, tempmin, tempmax } = options;
@ -23,6 +24,7 @@ export default function Resources({ options }) {
<Disk key={disk} options={{ disk }} expanded={expanded} diskUnits={diskUnits} refresh={refresh} /> <Disk key={disk} options={{ disk }} expanded={expanded} diskUnits={diskUnits} refresh={refresh} />
)) ))
: options.disk && <Disk options={options} expanded={expanded} diskUnits={diskUnits} refresh={refresh} />} : options.disk && <Disk options={options} expanded={expanded} diskUnits={diskUnits} refresh={refresh} />}
{options.network && <Network options={options} refresh={refresh} />}
{options.cputemp && ( {options.cputemp && (
<CpuTemp expanded={expanded} units={units} refresh={refresh} tempmin={tempmin} tempmax={tempmax} /> <CpuTemp expanded={expanded} units={units} refresh={refresh} tempmin={tempmin} tempmax={tempmax} />
)} )}

View File

@ -3,6 +3,7 @@ import UsageBar from "../resources/usage-bar";
export default function Resource({ export default function Resource({
children, children,
icon, icon,
iconChildren,
value, value,
label, label,
expandedValue = "", expandedValue = "",
@ -17,7 +18,10 @@ export default function Resource({
<div <div
className={`flex-none flex flex-row items-center mr-3 py-1.5 information-widget-resource ${additionalClassNames}`} className={`flex-none flex flex-row items-center mr-3 py-1.5 information-widget-resource ${additionalClassNames}`}
> >
<Icon className="text-theme-800 dark:text-theme-200 w-5 h-5 resource-icon" /> <div className="flex flex-col items-center">
<Icon className="text-theme-800 dark:text-theme-200 w-5 h-5 resource-icon" />
{iconChildren}
</div>
<div className={`flex flex-col ml-3 text-left min-w-[85px] ${expanded ? " expanded" : ""}`}> <div className={`flex flex-col ml-3 text-left min-w-[85px] ${expanded ? " expanded" : ""}`}>
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between"> <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">{value}</div> <div className="pl-0.5">{value}</div>

View File

@ -8,6 +8,7 @@ const si = require("systeminformation");
export default async function handler(req, res) { export default async function handler(req, res) {
const { type, target } = req.query; const { type, target } = req.query;
let { interfaceName } = req.query;
if (type === "cpu") { if (type === "cpu") {
const load = await si.currentLoad(); const load = await si.currentLoad();
@ -57,6 +58,31 @@ export default async function handler(req, res) {
}); });
} }
if (type === "network"){
let networkData = await si.networkStats();
if(interfaceName !== "default" && interfaceName !== undefined && interfaceName !== "false"){
networkData = networkData.filter((network) => network.iface === interfaceName)['0'];
if(!networkData){
return res.status(404).json({
error: "Interface not found",
});
}
}else{
const interfaceDefault = await si.networkInterfaceDefault();
interfaceName = interfaceDefault
networkData = networkData.filter((network) => network.iface === interfaceDefault)['0'];
if(!networkData){
return res.status(404).json({
error: "Interface not found! Please specify a valid interface name.",
});
}
}
return res.status(200).json({
network: networkData,
interface: interfaceName
});
}
return res.status(400).json({ return res.status(400).json({
error: "invalid type", error: "invalid type",
}); });