diff --git a/hub/site/src/components/charts/bandwidth-chart.tsx b/hub/site/src/components/charts/bandwidth-chart.tsx index 79dc580..112a4e1 100644 --- a/hub/site/src/components/charts/bandwidth-chart.tsx +++ b/hub/site/src/components/charts/bandwidth-chart.tsx @@ -1,45 +1,30 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from '@/components/ui/chart' +import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' import { chartTimeData, formatShortDate } from '@/lib/utils' import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $chartTime } from '@/lib/stores' - -const chartConfig = { - recv: { - label: 'Received', - color: 'hsl(var(--chart-2))', - }, - sent: { - label: 'Sent', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig +import { SystemStatsRecord } from '@/types' export default function BandwidthChart({ - chartData, ticks, + systemData, }: { - chartData: { time: number; sent: number; recv: number }[] ticks: number[] + systemData: SystemStatsRecord[] }) { const chartTime = useStore($chartTime) - if (!chartData.length || !ticks.length) { + if (!systemData.length || !ticks.length) { return } return ( - + formatShortDate(data[0].payload.time)} + labelFormatter={(_, data) => formatShortDate(data[0].payload.created)} indicator="line" /> } /> diff --git a/hub/site/src/components/charts/cpu-chart.tsx b/hub/site/src/components/charts/cpu-chart.tsx index ccf2542..59e4c8e 100644 --- a/hub/site/src/components/charts/cpu-chart.tsx +++ b/hub/site/src/components/charts/cpu-chart.tsx @@ -1,39 +1,28 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from '@/components/ui/chart' +import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' import { chartTimeData, formatShortDate } from '@/lib/utils' import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $chartTime } from '@/lib/stores' - -const chartConfig = { - cpu: { - label: 'CPU Usage', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig +import { SystemStatsRecord } from '@/types' export default function CpuChart({ - chartData, ticks, + systemData, }: { - chartData: { time: number; cpu: number }[] ticks: number[] + systemData: SystemStatsRecord[] }) { const chartTime = useStore($chartTime) - if (!chartData.length || !ticks.length) { + if (!systemData.length || !ticks.length) { return } return ( - - + + Math.ceil(max)]} @@ -43,7 +32,7 @@ export default function CpuChart({ unit={'%'} /> formatShortDate(data[0].payload.time)} + labelFormatter={(_, data) => formatShortDate(data[0].payload.created)} indicator="line" /> } /> { - return Math.round(chartData[0]?.disk) - }, [chartData]) + return Math.round(systemData[0]?.stats.d) + }, [systemData]) // const ticks = useMemo(() => { // let ticks = [0] @@ -41,15 +30,15 @@ export default function DiskChart({ // return ticks // }, [diskSize]) - if (!chartData.length || !ticks.length) { + if (!systemData.length || !ticks.length) { return } return ( - + formatShortDate(data[0].payload.time)} + labelFormatter={(_, data) => formatShortDate(data[0].payload.created)} indicator="line" /> } /> diff --git a/hub/site/src/components/charts/disk-io-chart.tsx b/hub/site/src/components/charts/disk-io-chart.tsx index d5c79d3..16a936a 100644 --- a/hub/site/src/components/charts/disk-io-chart.tsx +++ b/hub/site/src/components/charts/disk-io-chart.tsx @@ -1,45 +1,30 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from '@/components/ui/chart' +import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' import { chartTimeData, formatShortDate } from '@/lib/utils' import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $chartTime } from '@/lib/stores' - -const chartConfig = { - read: { - label: 'Read', - color: 'hsl(var(--chart-1))', - }, - write: { - label: 'Write', - color: 'hsl(var(--chart-3))', - }, -} satisfies ChartConfig +import { SystemStatsRecord } from '@/types' export default function DiskIoChart({ - chartData, ticks, + systemData, }: { - chartData: { time: number; read: number; write: number }[] ticks: number[] + systemData: SystemStatsRecord[] }) { const chartTime = useStore($chartTime) - if (!chartData.length || !ticks.length) { + if (!systemData.length || !ticks.length) { return } return ( - + formatShortDate(data[0].payload.time)} + labelFormatter={(_, data) => formatShortDate(data[0].payload.created)} indicator="line" /> } /> diff --git a/hub/site/src/components/charts/mem-chart.tsx b/hub/site/src/components/charts/mem-chart.tsx index 11116c6..1951920 100644 --- a/hub/site/src/components/charts/mem-chart.tsx +++ b/hub/site/src/components/charts/mem-chart.tsx @@ -1,54 +1,36 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from '@/components/ui/chart' +import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' import { chartTimeData, formatShortDate } from '@/lib/utils' import { useMemo } from 'react' import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $chartTime } from '@/lib/stores' +import { SystemStatsRecord } from '@/types' export default function MemChart({ - chartData, ticks, + systemData, }: { - chartData: { time: number; mem: number; memUsed: number; memCache: number }[] ticks: number[] + systemData: SystemStatsRecord[] }) { const chartTime = useStore($chartTime) const totalMem = useMemo(() => { - const maxMem = Math.ceil(chartData[0]?.mem) + const maxMem = Math.ceil(systemData[0]?.stats.m) return maxMem > 2 && maxMem % 2 !== 0 ? maxMem + 1 : maxMem - }, [chartData]) + }, [systemData]) - const chartConfig = useMemo( - () => ({ - memCache: { - label: 'Cache / Buffers', - color: 'hsl(var(--chart-2))', - }, - memUsed: { - label: 'Used', - color: 'hsl(var(--chart-2))', - }, - }), - [] - ) satisfies ChartConfig - - if (!chartData.length || !ticks.length) { + if (!systemData.length || !ticks.length) { return } return ( - + a.name.localeCompare(b.name)} - labelFormatter={(_, data) => formatShortDate(data[0].payload.time)} + labelFormatter={(_, data) => formatShortDate(data[0].payload.created)} indicator="line" /> } /> diff --git a/hub/site/src/components/routes/system.tsx b/hub/site/src/components/routes/system.tsx index 69e52aa..c4719ff 100644 --- a/hub/site/src/components/routes/system.tsx +++ b/hub/site/src/components/routes/system.tsx @@ -25,22 +25,7 @@ export default function ServerDetail({ name }: { name: string }) { const chartTime = useStore($chartTime) const [ticks, setTicks] = useState([] as number[]) const [server, setServer] = useState({} as SystemRecord) - const [containers, setContainers] = useState([] as ContainerStatsRecord[]) - const [systemStats, setSystemStats] = useState([] as SystemStatsRecord[]) - const [cpuChartData, setCpuChartData] = useState([] as { time: number; cpu: number }[]) - const [memChartData, setMemChartData] = useState( - [] as { time: number; mem: number; memUsed: number; memCache: number }[] - ) - const [diskChartData, setDiskChartData] = useState( - [] as { time: number; disk: number; diskUsed: number }[] - ) - const [diskIoChartData, setDiskIoChartData] = useState( - [] as { time: number; read: number; write: number }[] - ) - const [bandwidthChartData, setBandwidthChartData] = useState( - [] as { time: number; sent: number; recv: number }[] - ) const [dockerCpuChartData, setDockerCpuChartData] = useState( [] as Record[] ) @@ -58,10 +43,6 @@ export default function ServerDetail({ name }: { name: string }) { const resetCharts = useCallback(() => { setSystemStats([]) - setCpuChartData([]) - setMemChartData([]) - setDiskChartData([]) - setBandwidthChartData([]) setDockerCpuChartData([]) setDockerMemChartData([]) }, []) @@ -78,6 +59,13 @@ export default function ServerDetail({ name }: { name: string }) { } }, [name, server, systems]) + // update server when new data is available + useEffect(() => { + if (updatedSystem.id === server.id) { + setServer(updatedSystem) + } + }, [updatedSystem]) + // get stats useEffect(() => { if (!server.id || !chartTime) { @@ -94,54 +82,21 @@ export default function ServerDetail({ name }: { name: string }) { sort: 'created', }) .then((records) => { - // console.log('sctats', records) + // convert created time to ms value + for (const record of records) { + record.created = new Date(record.created).getTime() + } setSystemStats(records) }) }, [server, chartTime]) - useEffect(() => { - if (updatedSystem.id === server.id) { - setServer(updatedSystem) - } - }, [updatedSystem]) - - // create cpu / mem / disk data for charts - useEffect(() => { - if (!systemStats.length) { - return - } - const cpuData = [] as typeof cpuChartData - const memData = [] as typeof memChartData - const diskData = [] as typeof diskChartData - const diskIoData = [] as typeof diskIoChartData - const networkData = [] as typeof bandwidthChartData - for (let { created, stats } of systemStats) { - const time = new Date(created).getTime() - cpuData.push({ time, cpu: stats.cpu }) - memData.push({ - time, - mem: stats.m, - memUsed: stats.mu, - memCache: stats.mb, - }) - diskData.push({ time, disk: stats.d, diskUsed: stats.du }) - diskIoData.push({ time, read: stats.dr, write: stats.dw }) - networkData.push({ time, sent: stats.ns, recv: stats.nr }) - } - setCpuChartData(cpuData) - setMemChartData(memData) - setDiskChartData(diskData) - setDiskIoChartData(diskIoData) - setBandwidthChartData(networkData) - }, [systemStats]) - useEffect(() => { if (!systemStats.length) { return } const now = new Date() const startTime = chartTimeData[chartTime].getOffset(now) - const scale = scaleTime([startTime.getTime(), now], [0, cpuChartData.length]) + const scale = scaleTime([startTime.getTime(), now], [0, systemStats.length]) setTicks(scale.ticks(chartTimeData[chartTime].ticks).map((d) => d.getTime())) }, [chartTime, systemStats]) @@ -161,12 +116,13 @@ export default function ServerDetail({ name }: { name: string }) { sort: 'created', }) .then((records) => { - setContainers(records) + makeContainerData(records) + // setContainers(records) }) }, [server, chartTime]) // container stats for charts - useEffect(() => { + const makeContainerData = useCallback((containers: ContainerStatsRecord[]) => { // console.log('containers', containers) const dockerCpuData = [] as Record[] const dockerMemData = [] as Record[] @@ -182,10 +138,10 @@ export default function ServerDetail({ name }: { name: string }) { dockerCpuData.push(cpuData) dockerMemData.push(memData) } - // console.log('containerMemData', containerMemData) setDockerCpuChartData(dockerCpuData) setDockerMemChartData(dockerMemData) - }, [containers]) + }, []) + const uptime = useMemo(() => { let uptime = server.info?.u || 0 if (uptime < 172800) { @@ -254,7 +210,7 @@ export default function ServerDetail({ name }: { name: string }) { - + {dockerCpuChartData.length > 0 && ( @@ -264,7 +220,7 @@ export default function ServerDetail({ name }: { name: string }) { )} - + {dockerMemChartData.length > 0 && ( @@ -277,15 +233,15 @@ export default function ServerDetail({ name }: { name: string }) { title="Disk Usage" description="Usage of partition where the root filesystem is mounted" > - + - + - + ) diff --git a/hub/site/src/types.d.ts b/hub/site/src/types.d.ts index 72ce2ac..86a0087 100644 --- a/hub/site/src/types.d.ts +++ b/hub/site/src/types.d.ts @@ -57,6 +57,7 @@ export interface SystemStats { export interface ContainerStatsRecord extends RecordModel { system: string stats: ContainerStats[] + created: string | number } interface ContainerStats { @@ -71,6 +72,7 @@ interface ContainerStats { export interface SystemStatsRecord extends RecordModel { system: string stats: SystemStats + created: string | number } export interface AlertRecord extends RecordModel {