diff --git a/ui/src/hooks/useChartData.tsx b/ui/src/hooks/useChartData.tsx index dd71cab..54536c7 100644 --- a/ui/src/hooks/useChartData.tsx +++ b/ui/src/hooks/useChartData.tsx @@ -1,6 +1,6 @@ import type { StatusMessage } from "@/services/types"; -import { addRealtimeData, getRealtimeData } from "@/services/data_service"; -import { formatTimestamp } from "@/services/utils"; +import { addDataPoint, getRealtimeData } from "@/services/store"; +import { formatTimestamp, calcPercentage } from "@/services/utils"; import { useEffect } from "react"; export type ChartData = { @@ -22,82 +22,95 @@ export function useChartData(data: StatusMessage | null): ChartDataReturns { useEffect(() => { if (!data) return; - addRealtimeData(data); + addDataPoint(data); }, [data]); - const cpuPoints = getRealtimeData("cpu"); - const cpuUserPoints = getRealtimeData("cpu_user"); - const cpuSystemPoints = getRealtimeData("cpu_system"); - const cpuIdlePoints = getRealtimeData("cpu_idle"); - const cpuStealPoints = getRealtimeData("cpu_steal"); - const cpuIowaitPoints = getRealtimeData("cpu_iowait"); - const memoryPoints = getRealtimeData("memory"); - const swapPoints = getRealtimeData("swap"); - const networkUpPoints = getRealtimeData("network_up"); - const networkDownPoints = getRealtimeData("network_down"); + const realtimeData = getRealtimeData(); return { cpuData: { - labels: cpuPoints.map((p) => formatTimestamp(p.timestamp)), + labels: realtimeData.map((p) => formatTimestamp(p.timestamp)), datasets: [ { label: "Total CPU (%)", - data: cpuPoints.map((p) => p.value), + data: realtimeData.map(({ metrics }) => metrics.cpu.usage), color: "#3b82f6", }, { label: "User (%)", - data: cpuUserPoints.map((p) => p.value), + data: realtimeData.map( + ({ metrics }) => metrics.cpu.breakdown.user, + ), color: "#10b981", }, { label: "System (%)", - data: cpuSystemPoints.map((p) => p.value), + data: realtimeData.map( + ({ metrics }) => metrics.cpu.breakdown.system, + ), color: "#f59e0b", }, { label: "I/O Wait (%)", - data: cpuIowaitPoints.map((p) => p.value), + data: realtimeData.map( + ({ metrics }) => metrics.cpu.breakdown.iowait, + ), color: "#ef4444", }, { label: "Steal (%)", - data: cpuStealPoints.map((p) => p.value), + data: realtimeData.map( + ({ metrics }) => metrics.cpu.breakdown.steal, + ), color: "#8b5cf6", }, { label: "Idle (%)", - data: cpuIdlePoints.map((p) => p.value), + data: realtimeData.map( + ({ metrics }) => metrics.cpu.breakdown.idle, + ), color: "#6b7280", }, ], }, memoryData: { - labels: memoryPoints.map((p) => formatTimestamp(p.timestamp)), + labels: realtimeData.map((p) => formatTimestamp(p.timestamp)), datasets: [ { label: "Memory Usage (%)", - data: memoryPoints.map((p) => p.value), + data: realtimeData.map(({ metrics }) => + calcPercentage( + metrics.memory.used, + metrics.memory.total, + ), + ), color: "#10b981", }, { label: "Swap Usage (%)", - data: swapPoints.map((p) => p.value), + data: realtimeData.map(({ metrics }) => + calcPercentage( + metrics.memory.swap_used, + metrics.memory.swap_total, + ), + ), color: "#f59e0b", }, ], }, networkData: { - labels: networkUpPoints.map((p) => formatTimestamp(p.timestamp)), + labels: realtimeData.map((p) => formatTimestamp(p.timestamp)), datasets: [ { label: "Upload (B/s)", - data: networkUpPoints.map((p) => p.value), + data: realtimeData.map(({ metrics }) => metrics.network.up), color: "#ef4444", }, { label: "Download (B/s)", - data: networkDownPoints.map((p) => p.value), + data: realtimeData.map( + ({ metrics }) => metrics.network.down, + ), color: "#3b82f6", }, ], diff --git a/ui/src/pages/agent.tsx b/ui/src/pages/agent.tsx index 1833ebb..5f3eccc 100644 --- a/ui/src/pages/agent.tsx +++ b/ui/src/pages/agent.tsx @@ -13,7 +13,7 @@ import { getLastMessage, setLastMessage } from "@/services/store"; import { formatBytes, formatPercentage, - breakdownMetrics, + calcPercentage, } from "@/services/utils"; import { initializeConnection } from "@/services/websocket"; import { useEffect, useState } from "react"; @@ -54,19 +54,18 @@ export function AgentPage() { return "critical"; }; - const { - cpuThreads, - cpuUsage, - memoryUsage, - memoryUsed, - memoryTotal, - diskUsage, - diskFree, - diskTotal, - networkUp, - networkDown, - } = breakdownMetrics(message?.metrics); + const cpuUsage = metrics?.cpu.usage ?? 0; + const memoryUsed = metrics?.memory.used ?? 0; + const memoryTotal = metrics?.memory.total ?? 0; + const memoryUsage = calcPercentage(memoryUsed, memoryTotal); + + const diskFree = (metrics?.disk.total ?? 0) - (metrics?.disk.free ?? 0); + const diskTotal = metrics?.disk.total ?? 0; + const diskUsage = calcPercentage(diskFree, diskTotal); + + const networkUp = metrics?.network.up ?? 0; + const networkDown = metrics?.network.down ?? 0; const networkUsage = networkUp + networkDown; return ( @@ -92,7 +91,7 @@ export function AgentPage() { title: "CPU USAGE", value: formatPercentage(cpuUsage), status: getMetricStatus(cpuUsage), - subtitle: `${cpuThreads} threads`, + subtitle: `${metrics?.cpu.threads} threads`, }} > (); -const maxRealtimePoints = 50; - -function addDataPoint(metric: string, timestamp: string, value: number) { - if (!realtimeData.has(metric)) { - realtimeData.set(metric, []); - } - - const data = realtimeData.get(metric)!; - data.push({ timestamp, value }); - - if (data.length > maxRealtimePoints) { - data.shift(); - } -} - -export const addRealtimeData = (data: StatusMessage): void => { - const timestamp = data.timestamp; - - const { - cpuUsage, - cpuUser, - cpuSystem, - cpuIdle, - cpuSteal, - cpuIowait, - memoryUsage, - swapUsage, - networkUp, - networkDown, - } = breakdownMetrics(data.metrics); - - addDataPoint("cpu", timestamp, cpuUsage); - addDataPoint("cpu_user", timestamp, cpuUser); - addDataPoint("cpu_system", timestamp, cpuSystem); - addDataPoint("cpu_idle", timestamp, cpuIdle); - addDataPoint("cpu_steal", timestamp, cpuSteal); - addDataPoint("cpu_iowait", timestamp, cpuIowait); - addDataPoint("memory", timestamp, memoryUsage); - addDataPoint("swap", timestamp, swapUsage); - addDataPoint("network_up", timestamp, networkUp); - addDataPoint("network_down", timestamp, networkDown); -}; - -export function getRealtimeData(metric: string): HistoricalDataPoint[] { - return realtimeData.get(metric) || []; -} - -/* -export async function getHistoricalData(period: TimePeriod): Promise { - return ...todo -} - -function clearRealtimeData() { - realtimeData.clear(); -} -*/ diff --git a/ui/src/services/store.ts b/ui/src/services/store.ts index bfa854c..9b07ca1 100644 --- a/ui/src/services/store.ts +++ b/ui/src/services/store.ts @@ -10,3 +10,17 @@ export function getLastMessage(): StatusMessage | null { export function setLastMessage(message: StatusMessage) { store.set(message); } + +const realtimeData: StatusMessage[] = []; +const maxRealtimePoints = 50; + +export function addDataPoint(value: StatusMessage) { + realtimeData.push(value); + + if (realtimeData.length > maxRealtimePoints) { + realtimeData.shift(); + } +} +export function getRealtimeData(): StatusMessage[] { + return realtimeData ?? []; +} diff --git a/ui/src/services/utils.ts b/ui/src/services/utils.ts index 5e74c73..1fa3877 100644 --- a/ui/src/services/utils.ts +++ b/ui/src/services/utils.ts @@ -1,4 +1,4 @@ -import type { Metrics, UptimeMessage } from "@/services/types"; +import type { UptimeMessage } from "@/services/types"; export function isAgentOnline(data: UptimeMessage): boolean { const timeDiff = new Date().getTime() - new Date(data.last_seen).getTime(); @@ -66,54 +66,3 @@ export function calcPercentage( export function formatPercentage(val: number | undefined) { return `${(val ?? 0).toFixed(2)}%`; } - -export type BrokedownMetrics = { - cpuThreads: number; - cpuUsage: number; - cpuUser: number; - cpuSystem: number; - cpuIdle: number; - cpuSteal: number; - cpuIowait: number; - memoryUsage: number; - memoryUsed: number; - memoryTotal: number; - swapUsage: number; - diskUsage: number; - diskFree: number; - diskTotal: number; - networkUp: number; - networkDown: number; -}; - -export function breakdownMetrics( - metrics: Metrics | undefined, -): BrokedownMetrics { - return { - cpuThreads: metrics?.cpu.threads ?? 0, - cpuUsage: metrics?.cpu.usage ?? 0, - cpuUser: metrics?.cpu.breakdown.user ?? 0, - cpuSystem: metrics?.cpu.breakdown.system ?? 0, - cpuIdle: metrics?.cpu.breakdown.idle ?? 0, - cpuSteal: metrics?.cpu.breakdown.steal ?? 0, - cpuIowait: metrics?.cpu.breakdown.iowait ?? 0, - memoryUsage: calcPercentage( - metrics?.memory.used, - metrics?.memory.total, - ), - memoryUsed: metrics?.memory.used ?? 0, - memoryTotal: metrics?.memory.total ?? 0, - swapUsage: calcPercentage( - metrics?.memory.swap_used, - metrics?.memory.swap_total, - ), - diskUsage: calcPercentage( - (metrics?.disk.total ?? 0) - (metrics?.disk.free ?? 0), - metrics?.disk.total, - ), - diskFree: metrics?.disk.free ?? 0, - diskTotal: metrics?.disk.total ?? 0, - networkUp: (metrics?.network.up ?? 0) / 1024, - networkDown: (metrics?.network.down ?? 0) / 1024, - }; -}