chore: update node-os-utils to version 2.0.1 and refactor lodash imports

- Upgraded `node-os-utils` from version 1.3.7 to 2.0.1 across multiple package.json files.
- Removed deprecated `@types/node-os-utils` dependency.
- Refactored lodash imports to use a single import statement for consistency.
- Enhanced Docker stats monitoring by integrating new features from `node-os-utils` version 2.0.1.
This commit is contained in:
Mauricio Siu
2025-11-15 00:28:44 -06:00
parent b9324e6320
commit 69b7777db4
8 changed files with 112 additions and 39 deletions

View File

@@ -1,6 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod";
import copy from "copy-to-clipboard";
import { debounce } from "lodash";
import _ from "lodash";
import {
CheckIcon,
ChevronsUpDown,
@@ -236,7 +236,7 @@ export const RestoreBackup = ({
const currentDatabaseType = form.watch("databaseType");
const metadata = form.watch("metadata");
const debouncedSetSearch = debounce((value: string) => {
const debouncedSetSearch = _.debounce((value: string) => {
setDebouncedSearchTerm(value);
}, 350);

View File

@@ -1,5 +1,5 @@
import { FancyAnsi } from "fancy-ansi";
import { escapeRegExp } from "lodash";
import _ from "lodash";
import { Badge } from "@/components/ui/badge";
import {
Tooltip,
@@ -47,7 +47,7 @@ export function TerminalLine({ log, noTimestamp, searchTerm }: LogLineProps) {
}
const htmlContent = fancyAnsi.toHtml(text);
const searchRegex = new RegExp(`(${escapeRegExp(term)})`, "gi");
const searchRegex = new RegExp(`(${_.escapeRegExp(term)})`, "gi");
const modifiedContent = htmlContent.replace(
searchRegex,

View File

@@ -120,7 +120,7 @@
"next": "^15.3.2",
"next-i18next": "^15.4.2",
"next-themes": "^0.2.1",
"node-os-utils": "1.3.7",
"node-os-utils": "2.0.1",
"node-pty": "1.0.0",
"node-schedule": "2.1.1",
"nodemailer": "6.9.14",
@@ -163,7 +163,6 @@
"@types/lodash": "4.17.4",
"@types/micromatch": "4.0.9",
"@types/node": "^18.19.104",
"@types/node-os-utils": "1.3.4",
"@types/node-schedule": "2.1.6",
"@types/nodemailer": "^6.4.17",
"@types/qrcode": "^1.5.5",

View File

@@ -6,7 +6,9 @@ import {
recordAdvancedStats,
validateRequest,
} from "@dokploy/server";
import { OSUtils } from "node-os-utils";
import { WebSocketServer } from "ws";
import { formatBytes } from "@/components/dashboard/database/backups/restore-backup";
export const setupDockerStatsMonitoringSocketServer = (
server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>,
@@ -49,6 +51,83 @@ export const setupDockerStatsMonitoringSocketServer = (
}
const intervalId = setInterval(async () => {
try {
// Special case: when monitoring "dokploy", get host system stats instead of container stats
if (appName === "dokploy") {
const osutils = new OSUtils();
// Get CPU usage
const cpuResult = await osutils.cpu.usage();
const cpuUsage = cpuResult.success ? cpuResult.data : 0;
// Get memory info
const memResult = await osutils.memory.info();
let memUsedGB = 0;
let memTotalGB = 0;
let memUsedPercent = 0;
if (memResult.success) {
memTotalGB = memResult.data.total.toGB();
memUsedGB = memResult.data.used.toGB();
memUsedPercent = memResult.data.usagePercentage;
}
// Get network stats from network.overview() or network.statsAsync()
let netInputBytes = 0;
let netOutputBytes = 0;
const networkOverview = await osutils.network.overview();
if (networkOverview.success) {
netInputBytes = networkOverview.data.totalRxBytes.toBytes();
netOutputBytes = networkOverview.data.totalTxBytes.toBytes();
}
// Get Block I/O from disk.stats() (available in v2.0!)
// If disk.stats() doesn't work in container, fallback to /proc/diskstats
let blockReadBytes = 0;
let blockWriteBytes = 0;
const diskStats = await osutils.disk.stats();
if (diskStats.success && diskStats.data.length > 0) {
for (const stat of diskStats.data) {
blockReadBytes += stat.readBytes.toBytes();
blockWriteBytes += stat.writeBytes.toBytes();
}
}
// Format memory usage similar to docker stats format: "used / total"
const memUsedFormatted = `${memUsedGB.toFixed(2)}GiB`;
const memTotalFormatted = `${memTotalGB.toFixed(2)}GiB`;
const memUsageFormatted = `${memUsedFormatted} / ${memTotalFormatted}`;
// Format network I/O
const netInputMb = netInputBytes / (1024 * 1024);
const netOutputMb = netOutputBytes / (1024 * 1024);
const netIOFormatted = `${netInputMb.toFixed(2)}MB / ${netOutputMb.toFixed(2)}MB`;
// Format Block I/O
const blockIOFormatted = `${formatBytes(blockReadBytes)} / ${formatBytes(blockWriteBytes)}`;
// Create a stat object compatible with recordAdvancedStats
const stat = {
CPUPerc: `${cpuUsage.toFixed(2)}%`,
MemPerc: `${memUsedPercent.toFixed(2)}%`,
MemUsage: memUsageFormatted,
BlockIO: blockIOFormatted,
NetIO: netIOFormatted,
Container: "dokploy",
ID: "host-system",
Name: "dokploy",
};
await recordAdvancedStats(stat, appName);
const data = await getLastAdvancedStatsFile(appName);
console.log(data);
ws.send(
JSON.stringify({
data,
}),
);
return;
}
const filter = {
status: ["running"],
...(appType === "application" && {