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