diff --git a/site/src/components/add-server.tsx b/site/src/components/add-server.tsx index f8cb8d2..b50ffa5 100644 --- a/site/src/components/add-server.tsx +++ b/site/src/components/add-server.tsx @@ -26,8 +26,8 @@ export function AddServerButton() { function copyDockerCompose(port: string) { copyToClipboard(`services: agent: - image: 'henrygd/ubik-agent' - container_name: 'ubik-agent' + image: 'henrygd/quoma-agent' + container_name: 'quoma-agent' restart: unless-stopped ports: - '${port}:45876' diff --git a/site/src/components/charts/container-mem-chart.tsx b/site/src/components/charts/container-mem-chart.tsx new file mode 100644 index 0000000..2a505aa --- /dev/null +++ b/site/src/components/charts/container-mem-chart.tsx @@ -0,0 +1,110 @@ +'use client' + +import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from '@/components/ui/chart' +import { useMemo } from 'react' +import { formatShortDate, formatShortTime } from '@/lib/utils' +import Spinner from '../spinner' + +export default function ({ + chartData, + max, +}: { + chartData: Record[] + max: number +}) { + console.log('max', max) + const chartConfig = useMemo(() => { + let config = {} as Record< + string, + { + label: string + color: string + } + > + const totalUsage = {} as Record + for (let stats of chartData) { + for (let key in stats) { + if (key === 'time') { + continue + } + if (!(key in totalUsage)) { + totalUsage[key] = 0 + } + // @ts-ignore + totalUsage[key] += stats[key] + } + } + let keys = Object.keys(totalUsage) + keys.sort((a, b) => (totalUsage[a] > totalUsage[b] ? -1 : 1)) + const length = keys.length + for (let i = 0; i < length; i++) { + const key = keys[i] + const hue = ((i * 360) / length) % 360 + config[key] = { + label: key, + color: `hsl(${hue}, 60%, 60%)`, + } + } + return config satisfies ChartConfig + }, [chartData]) + + if (!chartData.length) { + return + } + + return ( + + + + `${Math.ceil(v / 1024)} GiB`} + /> + + { + // console.log('itemSorter', item) + // return -item.value + // }} + content={} + /> + {Object.keys(chartConfig).map((key) => ( + + ))} + + + ) +} diff --git a/site/src/components/logo.tsx b/site/src/components/logo.tsx index 3a2681f..af017ed 100644 --- a/site/src/components/logo.tsx +++ b/site/src/components/logo.tsx @@ -1,7 +1,8 @@ export function Logo({ className }: { className?: string }) { return ( - - + // audiowide + + ) } diff --git a/site/src/components/routes/server.tsx b/site/src/components/routes/server.tsx index 61a1d6e..fae5992 100644 --- a/site/src/components/routes/server.tsx +++ b/site/src/components/routes/server.tsx @@ -8,7 +8,8 @@ import CpuChart from '../charts/cpu-chart' import MemChart from '../charts/mem-chart' import DiskChart from '../charts/disk-chart' import ContainerCpuChart from '../charts/container-cpu-chart' -import { CpuIcon } from 'lucide-react' +import { CpuIcon, MemoryStickIcon } from 'lucide-react' +import ContainerMemChart from '../charts/container-mem-chart' // const CpuChart = lazy(() => import('../cpu-chart')) @@ -42,14 +43,17 @@ export default function ServerDetail({ name }: { name: string }) { const [containerCpuChartData, setContainerCpuChartData] = useState( [] as Record[] ) + const [containerMemChartData, setContainerMemChartData] = useState( + [] as Record[] + ) useEffect(() => { document.title = name return () => { setContainerCpuChartData([]) setCpuChartData({} as { max: number; data: { time: string; cpu: number }[] }) - setMemChartData([] as { time: string; mem: number; memUsed: number }[]) - setDiskChartData([] as { time: string; disk: number; diskUsed: number }[]) + setMemChartData([]) + setDiskChartData([]) } }, [name]) @@ -76,16 +80,18 @@ export default function ServerDetail({ name }: { name: string }) { if (!serverStats.length) { return } + let maxCpu = 0 const cpuData = [] as { time: string; cpu: number }[] const memData = [] as { time: string; mem: number; memUsed: number }[] const diskData = [] as { time: string; disk: number; diskUsed: number }[] for (let { created, stats } of serverStats) { cpuData.push({ time: created, cpu: stats.cpu }) + maxCpu = Math.max(maxCpu, stats.cpu) memData.push({ time: created, mem: stats.mem, memUsed: stats.memUsed }) diskData.push({ time: created, disk: stats.disk, diskUsed: stats.diskUsed }) } setCpuChartData({ - max: Math.ceil(Math.max(...cpuData.map((d) => d.cpu))), + max: Math.ceil(maxCpu), data: cpuData.reverse(), }) setMemChartData(memData.reverse()) @@ -125,15 +131,20 @@ export default function ServerDetail({ name }: { name: string }) { useEffect(() => { console.log('containers', containers) const containerCpuData = [] as Record[] + const containerMemData = [] as Record[] for (let { created, stats } of containers) { - let obj = { time: created } as Record - for (let { name, cpu } of stats) { - obj[name] = cpu + let cpuData = { time: created } as Record + let memData = { time: created } as Record + for (let container of stats) { + cpuData[container.name] = container.cpu + memData[container.name] = container.mem } - containerCpuData.push(obj) + containerCpuData.push(cpuData) + containerMemData.push(memData) } setContainerCpuChartData(containerCpuData.reverse()) + setContainerMemChartData(containerMemData.reverse()) }, [containers]) return ( @@ -175,9 +186,28 @@ export default function ServerDetail({ name }: { name: string }) { Precise usage at the recorded time - {/* }> */} - - {/* */} + }> + + + + + + + + Docker Memory Usage + + {' '} + Memory usage of docker containers + + + }> + {server?.stats?.mem && ( + + )} + diff --git a/site/src/components/server-table/data-table.tsx b/site/src/components/server-table/data-table.tsx index 26d00fd..46a14c3 100644 --- a/site/src/components/server-table/data-table.tsx +++ b/site/src/components/server-table/data-table.tsx @@ -69,7 +69,7 @@ function CellFormatter(info: CellContext) { } return (
- + Actions - { navigate(`/server/${system.name}`) }} > View details + */} + console.log('pause server')}> + Pause navigator.clipboard.writeText(system.ip)}> Copy IP address diff --git a/site/src/main.tsx b/site/src/main.tsx index 334a51c..bf4b436 100644 --- a/site/src/main.tsx +++ b/site/src/main.tsx @@ -10,7 +10,7 @@ import { buttonVariants } from './components/ui/button.tsx' import { Github } from 'lucide-react' import { useStore } from '@nanostores/react' import { Toaster } from './components/ui/toaster.tsx' -import { Can, Logo } from './components/logo.tsx' +import { Logo } from './components/logo.tsx' import { TooltipProvider, Tooltip, @@ -51,19 +51,20 @@ const Layout = () => { return ( <>
-
+
{ e.preventDefault() navigate('/') }} > - + diff --git a/site/src/types.d.ts b/site/src/types.d.ts index f711911..4a0be7d 100644 --- a/site/src/types.d.ts +++ b/site/src/types.d.ts @@ -27,7 +27,7 @@ interface ContainerStats { name: string cpu: number mem: number - mempct: number + memPct: number } export interface SystemStatsRecord extends RecordModel {