Application status

This commit is contained in:
2025-12-31 16:48:31 +01:00
parent b3eea5a2fd
commit cd723a6487
8 changed files with 53 additions and 48 deletions
+9 -4
View File
@@ -20,9 +20,10 @@ export default function ApplicationsPage() {
}; };
fetch(); fetch();
}, []);
console.log(applications); const iid = setInterval(fetch, 3000);
return () => clearInterval(iid);
}, []);
return ( return (
<DashboardLayout <DashboardLayout
@@ -77,7 +78,9 @@ export default function ApplicationsPage() {
<div className="text-xs text-muted-foreground mb-1">CPU</div> <div className="text-xs text-muted-foreground mb-1">CPU</div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Progress value={app.cpu} className="w-full" /> <Progress value={app.cpu} className="w-full" />
<span className="text-xs font-mono w-8">{app.cpu}%</span> <span className="text-xs font-mono w-8">
{app.cpu.toFixed(1)}%
</span>
</div> </div>
</div> </div>
@@ -88,7 +91,9 @@ export default function ApplicationsPage() {
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Progress value={app.memory} className="w-full" /> <Progress value={app.memory} className="w-full" />
<span className="text-xs font-mono w-8">{app.memory}%</span> <span className="text-xs font-mono w-8">
{app.memory.toFixed(1)}%
</span>
</div> </div>
</div> </div>
+11 -15
View File
@@ -35,7 +35,7 @@ type ContainerSummary = {
status: "running" | "stopped"; status: "running" | "stopped";
uptime: string; uptime: string;
cpu: number; cpu: number;
memory: string; memory: number;
}; };
async function summarizeContainer( async function summarizeContainer(
@@ -56,12 +56,6 @@ async function summarizeContainer(
const stats = await getContainerStats(container.Id); const stats = await getContainerStats(container.Id);
// 5. CPU and memory
const cpu = stats?.cpu_stats?.cpu_usage?.total_usage || 0;
const memory = `${formatBytes(
stats?.memory_stats?.usage || 0
)} / ${formatBytes(stats?.memory_stats?.max_usage || 0)}`;
return { return {
id: shortId, id: shortId,
name, name,
@@ -69,8 +63,8 @@ async function summarizeContainer(
node: nodeName, node: nodeName,
status, status,
uptime, uptime,
cpu, cpu: stats?.cpu || 0,
memory, memory: stats?.memory || 0,
}; };
} }
@@ -194,18 +188,18 @@ export default function ContainersPage() {
<td className="py-3 px-4">{container.node}</td> <td className="py-3 px-4">{container.node}</td>
<td className="py-3 px-4">{/* {container.status} */}</td> <td className="py-3 px-4">{container.status}</td>
<td className="py-3 px-4 font-mono text-xs"> <td className="py-3 px-4 font-mono text-xs">
{container.uptime} {container.uptime}
</td> </td>
<td className="py-3 px-4 font-mono text-xs"> <td className="py-3 px-4 font-mono text-xs">
{container.cpu} {container.cpu.toFixed(1)}%
</td> </td>
<td className="py-3 px-4 font-mono text-xs"> <td className="py-3 px-4 font-mono text-xs">
{container.memory} {container.memory.toFixed(1)}%
</td> </td>
<td className="py-3 px-4"> <td className="py-3 px-4">
@@ -249,7 +243,7 @@ export default function ContainersPage() {
<Container className="w-4 h-4 text-muted-foreground" /> <Container className="w-4 h-4 text-muted-foreground" />
<span className="font-mono text-sm">{container.name}</span> <span className="font-mono text-sm">{container.name}</span>
</div> </div>
{/* {container.status} */} {container.status}
</div> </div>
<div className="text-[10px] font-mono text-muted-foreground"> <div className="text-[10px] font-mono text-muted-foreground">
@@ -271,11 +265,13 @@ export default function ContainersPage() {
</div> </div>
<div> <div>
<span className="text-muted-foreground">CPU</span> <span className="text-muted-foreground">CPU</span>
<div className="font-mono">{container.cpu}</div> <div className="font-mono">{container.cpu.toFixed(1)}%</div>
</div> </div>
<div> <div>
<span className="text-muted-foreground">Memory</span> <span className="text-muted-foreground">Memory</span>
<div className="font-mono">{container.memory}</div> <div className="font-mono">
{container.memory.toFixed(1)}%
</div>
</div> </div>
</div> </div>
+8 -19
View File
@@ -11,8 +11,8 @@ import { useIsMobile } from "@/hooks/use-mobile";
import RadialChart from "@/components/RadialChart"; import RadialChart from "@/components/RadialChart";
import { getLiveNodes, getNodes } from "@/core/node"; import { getLiveNodes, getNodes } from "@/core/node";
import { average } from "@/lib/format"; import { average } from "@/lib/format";
import { ContainerStats } from "dockerode";
import { getContainerStats, getDocker } from "@/core/docker"; import { getContainerStats, getDocker } from "@/core/docker";
import { SimpleStats } from "@/lib/types";
const cpuChartConfig = { const cpuChartConfig = {
cpu: { label: "CPU Usage", color: "var(--chart-1)" }, cpu: { label: "CPU Usage", color: "var(--chart-1)" },
@@ -43,7 +43,7 @@ export default function MonitoringPage() {
ramUsage: number; ramUsage: number;
}>(); }>();
const [containerStats, SetContainerStats] = useState< const [containerStats, SetContainerStats] = useState<
(ContainerStats & { name: string })[] (SimpleStats & { name: string })[]
>([]); >([]);
useEffect(() => { useEffect(() => {
@@ -89,7 +89,7 @@ export default function MonitoringPage() {
}) })
) )
) )
).filter((s): s is ContainerStats & { name: string } => s !== undefined) ).filter((s): s is SimpleStats & { name: string } => s !== undefined)
); );
console.log(containerStats); console.log(containerStats);
@@ -207,31 +207,20 @@ export default function MonitoringPage() {
<div> <div>
<div className="flex justify-between text-[10px] text-muted-foreground mb-1"> <div className="flex justify-between text-[10px] text-muted-foreground mb-1">
<span>CPU</span> <span>CPU</span>
<span> <span>{container.cpu.toFixed(1)}%</span>
{container?.cpu_stats?.cpu_usage?.total_usage}%
</span>
</div> </div>
<Progress <Progress value={container.cpu} className="w-full" />
value={container?.cpu_stats?.cpu_usage?.total_usage}
className="w-full"
/>
</div> </div>
<div> <div>
<div className="flex justify-between text-[10px] text-muted-foreground mb-1"> <div className="flex justify-between text-[10px] text-muted-foreground mb-1">
<span>Memory</span> <span>Memory</span>
<span>{container?.memory_stats?.usage}%</span> <span>{container.memory.toFixed(1)}%</span>
</div> </div>
<Progress <Progress value={container.memory} className="w-full" />
value={container?.memory_stats?.usage}
className="w-full"
/>
</div> </div>
<div className="flex justify-between text-[10px] pt-1 border-t border-border"> <div className="flex justify-between text-[10px] pt-1 border-t border-border">
<span className="text-muted-foreground">Network</span> <span className="text-muted-foreground">Network</span>
<span className="font-mono"> <span className="font-mono"></span>
{container?.networks &&
container?.networks[0]?.tx_packets}
</span>
</div> </div>
</div> </div>
</div> </div>
+2 -3
View File
@@ -1,9 +1,8 @@
"use server"; "use server";
import axios from "axios"; import axios from "axios";
import { Docker, Node } from "@/lib/types"; import { Docker, Node, SimpleStats } from "@/lib/types";
import { verifySession } from "./auth/session"; import { verifySession } from "./auth/session";
import { ContainerStats } from "dockerode";
import { getNodes } from "./node"; import { getNodes } from "./node";
export async function getDocker(nodes: Node[]): Promise<Docker[]> { export async function getDocker(nodes: Node[]): Promise<Docker[]> {
@@ -24,7 +23,7 @@ export async function getDocker(nodes: Node[]): Promise<Docker[]> {
export async function getContainerStats( export async function getContainerStats(
containerId: string containerId: string
): Promise<ContainerStats | undefined> { ): Promise<SimpleStats | undefined> {
const nodes = await getNodes(); const nodes = await getNodes();
return ( return (
+7 -3
View File
@@ -1,12 +1,13 @@
"use server"; "use server";
import Docker from "dockerode"; import Docker, { Container, ContainerStats } from "dockerode";
import { randomUUID } from "crypto"; import { randomUUID } from "crypto";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import { exec } from "child_process"; import { exec } from "child_process";
import util from "util"; import util from "util";
import { ImageApp } from "@/lib/types"; import { ImageApp } from "@/lib/types";
import { CPUusage } from "@/lib/server/calc";
const docker = new Docker(); const docker = new Docker();
const execAsync = util.promisify(exec); const execAsync = util.promisify(exec);
@@ -42,6 +43,9 @@ export async function getApplications(): Promise<ImageApp[]> {
if (containerInfo.State === "running") { if (containerInfo.State === "running") {
const stats = await container.stats({ stream: false }); const stats = await container.stats({ stream: false });
totalMem += (stats.memory_stats.usage / stats.memory_stats.limit) * 100;
totalCpu += CPUusage(stats);
} }
} }
@@ -62,8 +66,8 @@ export async function getApplications(): Promise<ImageApp[]> {
image: imageName, image: imageName,
containers: relatedContainers.length, containers: relatedContainers.length,
replicas: `${running}/${relatedContainers.length}`, replicas: `${running}/${relatedContainers.length}`,
cpu: Math.round(totalCpu), cpu: totalCpu,
memory: Math.round(totalMem), memory: totalMem,
network: "—", network: "—",
status: running > 0 ? ("running" as const) : ("stopped" as const), status: running > 0 ? ("running" as const) : ("stopped" as const),
ports: [...ports], ports: [...ports],
+10 -3
View File
@@ -1,6 +1,8 @@
"use server"; "use server";
import Docker, { ContainerStats } from "dockerode"; import { CPUusage } from "@/lib/server/calc";
import { SimpleStats } from "@/lib/types";
import Docker from "dockerode";
const docker = new Docker(); const docker = new Docker();
@@ -12,8 +14,13 @@ export async function getDocker() {
export async function getContainerStats( export async function getContainerStats(
containerId: string containerId: string
): Promise<ContainerStats | undefined> { ): Promise<SimpleStats | undefined> {
return await docker.getContainer(containerId).stats(); const stats = await docker.getContainer(containerId).stats({ stream: false });
return {
cpu: CPUusage(stats),
memory: (stats.memory_stats.usage / stats.memory_stats.limit) * 100,
};
} }
export async function startContainer(containerId: string) { export async function startContainer(containerId: string) {
+5
View File
@@ -69,3 +69,8 @@ export interface ImageApp {
status: "running" | "stopped"; status: "running" | "stopped";
ports: string[]; ports: string[];
} }
export interface SimpleStats {
cpu: number;
memory: number;
}