From 8d5a57614e9983508734a8e2f0518f4d4c4a18f7 Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Wed, 15 Jan 2025 07:09:30 -0500 Subject: [PATCH] feat(frontend): move stats to a component, fix CPU usage --- frontend/src/components/ContainerStats.tsx | 36 ++++++++++++++++++++++ frontend/src/pages/containers/[name].tsx | 24 ++------------- 2 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 frontend/src/components/ContainerStats.tsx diff --git a/frontend/src/components/ContainerStats.tsx b/frontend/src/components/ContainerStats.tsx new file mode 100644 index 0000000..7926148 --- /dev/null +++ b/frontend/src/components/ContainerStats.tsx @@ -0,0 +1,36 @@ +import { useEffect, useState } from "react"; +import { ContainerStats as ContainerStatsType } from "dockerode"; +import { Typography } from "@mui/material"; + +export default function ContainerStats({ id }: { id: string }) { + const [stats, setStats] = useState(); + + useEffect(() => { + const sse = new EventSource(`/api/containers/${id}/stats`); + + sse.onmessage = ({ data }) => { + const parsed = JSON.parse(data); + setStats(parsed); + }; + + return () => { + sse.close(); + }; + }, []); + + if (!stats) { + return "Fetching container stats..."; + } + + const CPUPercentage = + ((stats.cpu_stats.cpu_usage.total_usage - + stats.precpu_stats.cpu_usage.total_usage) / + (stats.cpu_stats.system_cpu_usage - + stats.precpu_stats.system_cpu_usage)) * + stats.cpu_stats.online_cpus * + 100; + + return ( + CPU Usage: {(CPUPercentage || 0).toFixed(2) + "%"} + ); +} diff --git a/frontend/src/pages/containers/[name].tsx b/frontend/src/pages/containers/[name].tsx index 5b4355d..a2ca66b 100644 --- a/frontend/src/pages/containers/[name].tsx +++ b/frontend/src/pages/containers/[name].tsx @@ -1,8 +1,8 @@ import { useLoaderData, useRevalidator } from "react-router"; import { Container } from "../../types"; import { Button, ButtonGroup, Paper, Typography } from "@mui/material"; -import { useEffect, useState } from "react"; -import { ContainerStats } from "dockerode"; +import { useState } from "react"; +import ContainerStats from "../../components/ContainerStats"; interface Params { name: string; @@ -22,24 +22,6 @@ export default function ContainerPage() { return "Container not found"; } - const [stats, setStats] = useState(); - - useEffect(() => { - const statsSource = new EventSource( - `/api/containers/${container.name}/stats`, - ); - - statsSource.onmessage = ({ data }) => { - const parsed = JSON.parse(data); - setStats(parsed); - }; - - return () => { - statsSource.close(); - }; - }, []); - - console.log("stats", stats); const revalidator = useRevalidator(); const [isPowerStateLocked, setPowerStateLocked] = useState(); @@ -69,7 +51,7 @@ export default function ContainerPage() { - CPU Usage: {stats?.cpu_stats.cpu_usage.total_usage} + );