Application status
This commit is contained in:
@@ -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
@@ -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>
|
||||
|
||||
|
||||
@@ -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
@@ -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 (
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -69,3 +69,8 @@ export interface ImageApp {
|
||||
status: "running" | "stopped";
|
||||
ports: string[];
|
||||
}
|
||||
|
||||
export interface SimpleStats {
|
||||
cpu: number;
|
||||
memory: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user