From 96bb72eb99ae2dc5a9ef0c96b72078b487826d09 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 1 Feb 2025 19:27:10 -0600 Subject: [PATCH] refactor: update docker stats --- .../monitoring/docker/docker-block-chart.tsx | 8 +- .../monitoring/docker/docker-cpu-chart.tsx | 6 +- .../monitoring/docker/docker-memory-chart.tsx | 11 +- .../docker/docker-network-chart.tsx | 12 +- .../dashboard/monitoring/docker/show.tsx | 58 +++++---- apps/dokploy/server/wss/docker-stats.ts | 15 ++- packages/server/src/index.ts | 2 +- .../src/monitoring/{utilts.ts => utils.ts} | 112 +++--------------- packages/server/src/services/application.ts | 2 +- 9 files changed, 92 insertions(+), 134 deletions(-) rename packages/server/src/monitoring/{utilts.ts => utils.ts} (53%) diff --git a/apps/dokploy/components/dashboard/monitoring/docker/docker-block-chart.tsx b/apps/dokploy/components/dashboard/monitoring/docker/docker-block-chart.tsx index 57a3cbe2..790bf021 100644 --- a/apps/dokploy/components/dashboard/monitoring/docker/docker-block-chart.tsx +++ b/apps/dokploy/components/dashboard/monitoring/docker/docker-block-chart.tsx @@ -90,9 +90,11 @@ const CustomTooltip = ({ active, payload }: CustomTooltipProps) => { if (active && payload && payload.length && payload[0]) { return (
-

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

-

{`Read ${payload[0].payload.readMb.toFixed(2)} MB`}

-

{`Write: ${payload[0].payload.writeMb.toFixed(3)} MB`}

+ {payload[0].payload.time && ( +

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

+ )} +

{`Read ${payload[0].payload.readMb} `}

+

{`Write: ${payload[0].payload.writeMb} `}

); } diff --git a/apps/dokploy/components/dashboard/monitoring/docker/docker-cpu-chart.tsx b/apps/dokploy/components/dashboard/monitoring/docker/docker-cpu-chart.tsx index 41f20f8f..16355623 100644 --- a/apps/dokploy/components/dashboard/monitoring/docker/docker-cpu-chart.tsx +++ b/apps/dokploy/components/dashboard/monitoring/docker/docker-cpu-chart.tsx @@ -19,7 +19,7 @@ export const DockerCpuChart = ({ acummulativeData }: Props) => { return { name: `Point ${index + 1}`, time: item.time, - usage: item.value.toFixed(2), + usage: item.value.toString().split("%")[0], }; }); return ( @@ -75,7 +75,9 @@ const CustomTooltip = ({ active, payload }: CustomTooltipProps) => { if (active && payload && payload.length && payload[0]) { return (
-

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

+ {payload[0].payload.time && ( +

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

+ )}

{`CPU Usage: ${payload[0].payload.usage}%`}

); diff --git a/apps/dokploy/components/dashboard/monitoring/docker/docker-memory-chart.tsx b/apps/dokploy/components/dashboard/monitoring/docker/docker-memory-chart.tsx index 36f1edb8..f98e01e1 100644 --- a/apps/dokploy/components/dashboard/monitoring/docker/docker-memory-chart.tsx +++ b/apps/dokploy/components/dashboard/monitoring/docker/docker-memory-chart.tsx @@ -9,6 +9,7 @@ import { YAxis, } from "recharts"; import type { DockerStatsJSON } from "./show"; +import { convertMemoryToBytes } from "./show"; interface Props { acummulativeData: DockerStatsJSON["memory"]; @@ -23,7 +24,8 @@ export const DockerMemoryChart = ({ return { time: item.time, name: `Point ${index + 1}`, - usage: (item.value.used / 1024 ** 3).toFixed(2), + // @ts-ignore + usage: (convertMemoryToBytes(item.value.used) / 1024 ** 3).toFixed(2), }; }); return ( @@ -75,10 +77,13 @@ interface CustomTooltipProps { } const CustomTooltip = ({ active, payload }: CustomTooltipProps) => { - if (active && payload && payload.length && payload[0]) { + if (active && payload && payload.length && payload[0] && payload[0].payload) { return (
-

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

+ {payload[0].payload.time && ( +

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

+ )} +

{`Memory usage: ${payload[0].payload.usage} GB`}

); diff --git a/apps/dokploy/components/dashboard/monitoring/docker/docker-network-chart.tsx b/apps/dokploy/components/dashboard/monitoring/docker/docker-network-chart.tsx index b522603d..58cd2400 100644 --- a/apps/dokploy/components/dashboard/monitoring/docker/docker-network-chart.tsx +++ b/apps/dokploy/components/dashboard/monitoring/docker/docker-network-chart.tsx @@ -19,8 +19,8 @@ export const DockerNetworkChart = ({ acummulativeData }: Props) => { return { time: item.time, name: `Point ${index + 1}`, - inMB: item.value.inputMb.toFixed(2), - outMB: item.value.outputMb.toFixed(2), + inMB: item.value.inputMb, + outMB: item.value.outputMb, }; }); return ( @@ -86,9 +86,11 @@ const CustomTooltip = ({ active, payload }: CustomTooltipProps) => { if (active && payload && payload.length && payload[0]) { return (
-

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

-

{`In MB Usage: ${payload[0].payload.inMB} MB`}

-

{`Out MB Usage: ${payload[0].payload.outMB} MB`}

+ {payload[0].payload.time && ( +

{`Date: ${format(new Date(payload[0].payload.time), "PPpp")}`}

+ )} +

{`In Usage: ${payload[0].payload.inMB} `}

+

{`Out Usage: ${payload[0].payload.outMB} `}

); } diff --git a/apps/dokploy/components/dashboard/monitoring/docker/show.tsx b/apps/dokploy/components/dashboard/monitoring/docker/show.tsx index a457f35e..d2513b70 100644 --- a/apps/dokploy/components/dashboard/monitoring/docker/show.tsx +++ b/apps/dokploy/components/dashboard/monitoring/docker/show.tsx @@ -22,8 +22,6 @@ const defaultData = { memory: { value: { used: 0, - free: 0, - usedPercentage: 0, total: 0, }, time: "", @@ -60,8 +58,6 @@ export interface DockerStats { memory: { value: { used: number; - free: number; - usedPercentage: number; total: number; }; time: string; @@ -100,6 +96,30 @@ export type DockerStatsJSON = { disk: DockerStats["disk"][]; }; +export const convertMemoryToBytes = ( + memoryString: string | undefined, +): number => { + if (!memoryString || typeof memoryString !== "string") { + return 0; + } + + const value = Number.parseFloat(memoryString) || 0; + const unit = memoryString.replace(/[0-9.]/g, "").trim(); + + switch (unit) { + case "KiB": + return value * 1024; + case "MiB": + return value * 1024 * 1024; + case "GiB": + return value * 1024 * 1024 * 1024; + case "TiB": + return value * 1024 * 1024 * 1024 * 1024; + default: + return value; + } +}; + export const DockerMonitoring = ({ appName, appType = "application", @@ -208,7 +228,7 @@ export const DockerMonitoring = ({
- Used: {currentData.cpu.value.toFixed(2)}% + Used: {currentData.cpu.value}% - @@ -228,20 +247,26 @@ export const DockerMonitoring = ({
- {`Used: ${(currentData.memory.value.used / 1024 ** 3).toFixed(2)} GB / Limit: ${(currentData.memory.value.total / 1024 ** 3).toFixed(2)} GB`} + {`Used: ${currentData.memory.value.used} / Limit: ${currentData.memory.value.total} `}
- {appName === "dokploy" && ( @@ -274,17 +299,12 @@ export const DockerMonitoring = ({
- {`Read: ${currentData.block.value.readMb.toFixed( - 2, - )} MB / Write: ${currentData.block.value.writeMb.toFixed( - 3, - )} MB`} + {`Read: ${currentData.block.value.readMb} / Write: ${currentData.block.value.writeMb} `}
- @@ -294,11 +314,7 @@ export const DockerMonitoring = ({
- {`In MB: ${currentData.network.value.inputMb.toFixed( - 2, - )} MB / Out MB: ${currentData.network.value.outputMb.toFixed( - 2, - )} MB`} + {`In MB: ${currentData.network.value.inputMb} / Out MB: ${currentData.network.value.outputMb} `} { const { MONITORING_PATH } = paths(); @@ -12,29 +21,20 @@ export const recordAdvancedStats = async ( await promises.mkdir(path, { recursive: true }); - const cpuPercent = calculateCpuUsagePercent( - stats.cpu_stats, - stats.precpu_stats, - ); - const memoryStats = calculateMemoryStats(stats.memory_stats); - const blockIO = calculateBlockIO(stats.blkio_stats); - const networkUsage = calculateNetworkUsage(stats.networks); - - await updateStatsFile(appName, "cpu", cpuPercent); + await updateStatsFile(appName, "cpu", stats.CPUPerc); await updateStatsFile(appName, "memory", { - used: memoryStats.used, - free: memoryStats.free, - usedPercentage: memoryStats.usedPercentage, - total: memoryStats.total, + used: stats.MemUsage.split(" ")[0], + total: stats.MemUsage.split(" ")[2], }); + await updateStatsFile(appName, "block", { - readMb: blockIO.readMb, - writeMb: blockIO.writeMb, + readMb: stats.BlockIO.split(" ")[0], + writeMb: stats.BlockIO.split(" ")[2], }); await updateStatsFile(appName, "network", { - inputMb: networkUsage.inputMb, - outputMb: networkUsage.outputMb, + inputMb: stats.NetIO.split(" ")[0], + outputMb: stats.NetIO.split(" ")[2], }); if (appName === "dokploy") { @@ -122,77 +122,3 @@ export const getLastAdvancedStatsFile = async (appName: string) => { block: await readLastValueStatsFile(appName, "block"), }; }; - -const calculateCpuUsagePercent = ( - cpu_stats: Dockerode.ContainerStats["cpu_stats"], - precpu_stats: Dockerode.ContainerStats["precpu_stats"], -) => { - const cpuDelta = - cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage; - const systemDelta = - cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage; - - const numberCpus = - cpu_stats.online_cpus || - (cpu_stats.cpu_usage.percpu_usage - ? cpu_stats.cpu_usage.percpu_usage.length - : 1); - - if (systemDelta > 0 && cpuDelta > 0) { - return (cpuDelta / systemDelta) * numberCpus * 100.0; - } - return 0; -}; - -const calculateMemoryStats = ( - memory_stats: Dockerode.ContainerStats["memory_stats"], -) => { - const usedMemory = memory_stats.usage - (memory_stats.stats.cache || 0); - const availableMemory = memory_stats.limit; - const memoryUsedPercentage = (usedMemory / availableMemory) * 100.0; - - return { - used: usedMemory, - free: availableMemory - usedMemory, - usedPercentage: memoryUsedPercentage, - total: availableMemory, - }; -}; -const calculateBlockIO = ( - blkio_stats: Dockerode.ContainerStats["blkio_stats"], -) => { - let readIO = 0; - let writeIO = 0; - if (blkio_stats?.io_service_bytes_recursive) { - for (const io of blkio_stats.io_service_bytes_recursive) { - if (io.op === "read") { - readIO += io.value; - } else if (io.op === "write") { - writeIO += io.value; - } - } - } - return { - readMb: readIO / (1024 * 1024), - writeMb: writeIO / (1024 * 1024), - }; -}; - -const calculateNetworkUsage = ( - networks: Dockerode.ContainerStats["networks"], -) => { - let totalRx = 0; - let totalTx = 0; - - const stats = Object.keys(networks); - - for (const interfaceName of stats) { - const net = networks[interfaceName]; - totalRx += net?.rx_bytes || 0; - totalTx += net?.tx_bytes || 0; - } - return { - inputMb: totalRx / (1024 * 1024), - outputMb: totalTx / (1024 * 1024), - }; -}; diff --git a/packages/server/src/services/application.ts b/packages/server/src/services/application.ts index da1b50af..c102e8ed 100644 --- a/packages/server/src/services/application.ts +++ b/packages/server/src/services/application.ts @@ -6,7 +6,7 @@ import { buildAppName, cleanAppName, } from "@dokploy/server/db/schema"; -import { getAdvancedStats } from "@dokploy/server/monitoring/utilts"; +import { getAdvancedStats } from "@dokploy/server/monitoring/utils"; import { buildApplication, getBuildCommand,