diff --git a/src/pages/monitoring/MonitoringPage.tsx b/src/pages/monitoring/MonitoringPage.tsx index 1358624..aa814cb 100644 --- a/src/pages/monitoring/MonitoringPage.tsx +++ b/src/pages/monitoring/MonitoringPage.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useMemo, useState } from 'react'; -import { Card, Col, Row, Select, Tabs } from 'antd'; +import { Card, Col, Row, Select, Table, Tabs } from 'antd'; import { LineChart, Line, @@ -12,6 +12,7 @@ import { } from 'recharts'; import dayjs from 'dayjs'; import { useMetricsStore, NodeMetric } from '../../store/metricsStore'; +import { monitoringApi } from '../../api/monitoringApi'; const NODE_COLORS = ['#1677ff', '#52c41a', '#fa8c16', '#eb2f96', '#722ed1', '#13c2c2']; const TIME_RANGES = [ @@ -21,23 +22,35 @@ const TIME_RANGES = [ { label: '1 час', value: 60 }, ]; +const bytesToMb = (value?: number) => (value ?? 0) / 1048576; + const formatTime = (ts: string) => dayjs(ts).format('HH:mm:ss'); const buildChartData = (metrics: NodeMetric[]) => metrics.map((m) => ({ time: formatTime(m.timestamp), cpu: m.cpu_utilization ?? 0, - memoryMb: (m.memory_total ?? 0) / 1048576, + memoryMb: bytesToMb(m.memory_total), + memoryProcessesMb: bytesToMb(m.memory_processes), + memoryAtomMb: bytesToMb(m.memory_atom), + memoryBinaryMb: bytesToMb(m.memory_binary), + memoryEtsMb: bytesToMb(m.memory_ets), + memoryAvailableMb: bytesToMb(m.memory_available), ws: m.ws_connections ?? 0, runQueue: m.run_queue ?? 0, + processCount: m.process_count ?? 0, + activeSessions: m.active_sessions ?? 0, + ioIn: m.io_in ?? 0, + ioOut: m.io_out ?? 0, mnesiaCommits: m.mnesia_commits ?? 0, mnesiaFailures: m.mnesia_failures ?? 0, + tableSizes: m.table_sizes ?? {}, })); -const MetricChart: React.FC<{ data: ReturnType; lines: Array<{ key: string; color: string; name: string }> }> = ({ - data, - lines, -}) => ( +const MetricChart: React.FC<{ + data: ReturnType; + lines: Array<{ key: string; color: string; name: string }>; +}> = ({ data, lines }) => ( @@ -55,9 +68,38 @@ const MetricChart: React.FC<{ data: ReturnType; lines: Ar const MonitoringPage: React.FC = () => { const allHistory = useMetricsStore((s) => s.allHistory); const current = useMetricsStore((s) => s.current); + const setAllHistory = useMetricsStore((s) => s.setAllHistory); const filterVisibleHistory = useMetricsStore((s) => s.filterVisibleHistory); const visibleHistory = useMetricsStore((s) => s.visibleHistory); const [minutes, setMinutes] = useState(15); + const [loadingHistory, setLoadingHistory] = useState(false); + + useEffect(() => { + let cancelled = false; + + const loadHistory = async () => { + setLoadingHistory(true); + try { + const to = dayjs().toISOString(); + const from = dayjs().subtract(minutes, 'minute').toISOString(); + const metrics = await monitoringApi.getNodeMetrics(from, to); + if (!cancelled && metrics.length > 0) { + setAllHistory(metrics); + } + } catch { + // live WS дополняет историю; REST недоступен — не блокируем страницу + } finally { + if (!cancelled) { + setLoadingHistory(false); + } + } + }; + + loadHistory(); + return () => { + cancelled = true; + }; + }, [minutes, setAllHistory]); useEffect(() => { filterVisibleHistory(minutes); @@ -83,6 +125,7 @@ const MonitoringPage: React.FC = () => { const tabItems = allNodes.map((node, idx) => { const nodeMetrics = metricsByNode.get(node) || []; const chartData = buildChartData(nodeMetrics); + const latestTableSizes = chartData.at(-1)?.tableSizes ?? {}; const color = NODE_COLORS[idx % NODE_COLORS.length]; return { @@ -96,7 +139,21 @@ const MonitoringPage: React.FC = () => { data={chartData} lines={[ { key: 'cpu', color, name: 'CPU %' }, - { key: 'memoryMb', color: '#1890ff', name: 'Память МБ' }, + { key: 'memoryMb', color: '#1890ff', name: 'Память всего' }, + { key: 'memoryAvailableMb', color: '#13c2c2', name: 'Память доступно' }, + ]} + /> + + + + + @@ -108,6 +165,8 @@ const MonitoringPage: React.FC = () => { lines={[ { key: 'ws', color: '#52c41a', name: 'WS' }, { key: 'runQueue', color: '#fa8c16', name: 'Run queue' }, + { key: 'processCount', color: '#722ed1', name: 'Processes' }, + { key: 'activeSessions', color: '#1677ff', name: 'Sessions' }, ]} /> @@ -123,6 +182,34 @@ const MonitoringPage: React.FC = () => { /> + + + + + + + + ({ + table, + size, + }))} + columns={[ + { title: 'Таблица', dataIndex: 'table', key: 'table' }, + { title: 'Записей', dataIndex: 'size', key: 'size' }, + ]} + /> + + ), }; @@ -141,7 +228,9 @@ const MonitoringPage: React.FC = () => { {allNodes.length === 0 ? ( - Ожидание метрик по WebSocket… + + {loadingHistory ? 'Загрузка метрик…' : 'Ожидание метрик по WebSocket…'} + ) : ( )}