"use client"; import { DashboardLayout } from "@/components/dashboard/DashboardLayout"; import { Progress } from "@/components/ui/progress"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { type ChartConfig } from "@/components/ui/chart"; import GradientAreaChart from "@/components/GradientAreaChart"; import { getMetrics } from "@/lib/dockship/metrics"; import { useIsMobile } from "@/hooks/use-mobile"; import RadialChart from "@/components/RadialChart"; import { getLiveNodes, getNodes } from "@/lib/dockship/node"; import { average } from "@/lib/format"; import { getContainerStats, getDocker } from "@/lib/dockship/docker"; import { SimpleStats } from "@/lib/types"; import { useAsync, useAsyncInterval } from "@/hooks/use-async"; const cpuChartConfig = { cpu: { label: "CPU Usage", color: "var(--chart-1)" }, } satisfies ChartConfig; const memoryChartConfig = { memory: { label: "RAM Usage", color: "var(--chart-3)" }, } satisfies ChartConfig; const networkChartConfig = { in: { label: "Inbound", color: "var(--chart-2)" }, out: { label: "Outbound", color: "var(--chart-4)" }, } satisfies ChartConfig; export default function MonitoringPage() { const isMobile = useIsMobile(); // Metrics polling every 30 seconds const { value: metrics } = useAsyncInterval( "metrics", [], getMetrics, 30000, [], ); // Live nodes polling every 3 seconds const { value: liveData } = useAsyncInterval( "liveNodes", { cpuUsage: 0, ramUsage: 0 }, async () => { const nodes = await getLiveNodes(); return { cpuUsage: average(nodes, (n) => n.liveData?.cpu.usage || 0), ramUsage: average(nodes, (n) => n.liveData?.memory.usage || 0), }; }, 3000, [], ); // Container stats const { value: containerStats } = useAsync( "containerStats", [], async () => { const nodes = await getNodes(); const dockerNodes = await getDocker(nodes); return ( await Promise.all( dockerNodes.flatMap((node) => node.containers.map(async (c) => { const stats = await getContainerStats(c.Id); if (!stats) return undefined; return { ...stats, name: c.Names[0] }; }), ), ) ).filter((s): s is SimpleStats & { name: string } => s !== undefined); }, [], ); const containerCPU = containerStats.reduce((acc, val) => acc + val.cpu, 0); const containerMemory = containerStats.reduce( (acc, val) => acc + val.memory, 0, ); return ( {/* Summary Stats */} {isMobile ? (
CPU RAM con CPU con RAM
) : (
CPU usage
{liveData?.cpuUsage?.toFixed(1) || 0}%
Memory usage
{liveData?.ramUsage?.toFixed(1) || 0}%
Container CPU usage
{containerCPU.toFixed(1)}%
Container memory usage
{containerMemory.toFixed(1)}%
)} {/* CPU & Memory Charts */}
{/* Network Metrics */}
{/* Container Metrics */} Container Metrics
{containerStats.map((container) => (
{container.name}
CPU {container.cpu?.toFixed(1)}%
Memory {container.memory?.toFixed(1)}%
Network
))}
); }