feat: add global Docker network stats tracking and update HomeDashboard title

This commit is contained in:
SaelixCode
2026-03-03 09:10:24 -05:00
parent 587e88e93d
commit 1fd078616a
3 changed files with 57 additions and 14 deletions
+5 -13
View File
@@ -3,7 +3,7 @@ import cors from 'cors';
import cookieParser from 'cookie-parser';
import WebSocket from 'ws';
import jwt from 'jsonwebtoken';
import DockerController from './services/DockerController';
import DockerController, { globalDockerNetwork } from './services/DockerController';
import { FileSystemService } from './services/FileSystemService';
import { ComposeService } from './services/ComposeService';
import { ConfigService } from './services/ConfigService';
@@ -607,24 +607,16 @@ app.get('/api/stats', async (req: Request, res: Response) => {
// Get host system stats
app.get('/api/system/stats', async (req: Request, res: Response) => {
try {
const [currentLoad, mem, fsSize, networkStats] = await Promise.all([
const [currentLoad, mem, fsSize] = await Promise.all([
si.currentLoad(),
si.mem(),
si.fsSize(),
si.networkStats(),
si.fsSize()
]);
let rxSec = Math.max(0, globalDockerNetwork.rxSec);
let txSec = Math.max(0, globalDockerNetwork.txSec);
let rxBytes = 0;
let txBytes = 0;
let rxSec = 0;
let txSec = 0;
networkStats.forEach(net => {
rxBytes += net.rx_bytes || 0;
txBytes += net.tx_bytes || 0;
rxSec += net.rx_sec || 0;
txSec += net.tx_sec || 0;
});
// Find the main mount (usually the largest or root mount)
const mainDisk = fsSize.find(fs => fs.mount === '/' || fs.mount === 'C:') || fsSize[0];
+51
View File
@@ -449,4 +449,55 @@ class DockerController {
}
}
export let globalDockerNetwork = { rxSec: 0, txSec: 0 };
let lastNetSum = { rx: 0, tx: 0, timestamp: Date.now() };
export const updateGlobalDockerNetwork = async () => {
try {
const dockerController = DockerController.getInstance();
const containers = await dockerController.getRunningContainers();
const statsResults = await Promise.allSettled(
containers.map(c => dockerController.getContainerStatsStream(c.Id))
);
let currentRxSum = 0;
let currentTxSum = 0;
for (const result of statsResults) {
if (result.status === 'fulfilled') {
try {
const stats = typeof result.value === 'string' ? JSON.parse(result.value) : result.value;
if (stats.networks) {
for (const [_, net] of Object.entries(stats.networks) as any) {
currentRxSum += net.rx_bytes || 0;
currentTxSum += net.tx_bytes || 0;
}
}
} catch (e) {
// ignore parsing errors
}
}
}
const now = Date.now();
const timeDiffSeconds = (now - lastNetSum.timestamp) / 1000;
if (timeDiffSeconds > 0) {
const rxDelta = currentRxSum >= lastNetSum.rx ? currentRxSum - lastNetSum.rx : 0;
const txDelta = currentTxSum >= lastNetSum.tx ? currentTxSum - lastNetSum.tx : 0;
globalDockerNetwork.rxSec = rxDelta / timeDiffSeconds;
globalDockerNetwork.txSec = txDelta / timeDiffSeconds;
}
lastNetSum = { rx: currentRxSum, tx: currentTxSum, timestamp: now };
} catch (error) {
console.error('Failed to update global docker network stats:', error);
}
};
// Start the interval tracker
setInterval(updateGlobalDockerNetwork, 3000);
export default DockerController;
+1 -1
View File
@@ -172,7 +172,7 @@ export default function HomeDashboard() {
<Card className="rounded-xl border-muted bg-card">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground">Host Network</CardTitle>
<CardTitle className="text-sm font-medium text-muted-foreground">Docker Network</CardTitle>
<Network className="h-4 w-4 text-cyan-500" />
</CardHeader>
<CardContent>