diff --git a/src/app/page.tsx b/src/app/page.tsx index b424696..147bcd0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -10,6 +10,7 @@ import NodeTable from '@/components/report/NodeTable'; import NasTable from '@/components/report/NasTable'; import NetworkTable from '@/components/report/NetworkTable'; import AlertPanel from '@/components/report/AlertPanel'; +import NetworkAlertPanel from '@/components/report/NetworkAlertPanel'; import ErrorBoundary from '@/components/ErrorBoundary'; function getDefaultRange() { @@ -172,18 +173,33 @@ export default function Home() { {data.metrics.nas && data.metrics.nas.length > 0 && ( - - - +
+ + + + + + +
)} - - - +
+ + + + + + +
- - - +
+ + + + + + +
diff --git a/src/components/report/AlertPanel.tsx b/src/components/report/AlertPanel.tsx index 91648db..5c3339c 100644 --- a/src/components/report/AlertPanel.tsx +++ b/src/components/report/AlertPanel.tsx @@ -5,7 +5,7 @@ import { formatTimestamp, formatPercent } from '@/lib/formatters'; interface AlertPanelProps { instances: MetricInstance[]; - type: 'cpu' | 'memory' | 'disk'; + type: 'cpu' | 'memory' | 'disk' | 'nas'; height?: number; } @@ -49,7 +49,7 @@ function generateAlerts(instances: MetricInstance[], type: string): Alert[] { message: `${formatTimestamp(peak.startTime)} ~ ${formatTimestamp(peak.endTime)} Peak (max: ${formatPercent(peak.maxValue)})`, }); }); - } else if (type === 'disk') { + } else if (type === 'disk' || type === 'nas') { if (inst.stats.max > 80) { alerts.push({ level: inst.stats.max > 90 ? 'critical' : 'warning', diff --git a/src/components/report/NetworkAlertPanel.tsx b/src/components/report/NetworkAlertPanel.tsx new file mode 100644 index 0000000..0d6b50d --- /dev/null +++ b/src/components/report/NetworkAlertPanel.tsx @@ -0,0 +1,59 @@ +'use client'; + +import type { NetworkMetrics } from '@/types/metrics'; +import { formatTimestamp, formatBytesPerSec } from '@/lib/formatters'; + +interface NetworkAlertPanelProps { + data: NetworkMetrics; + height?: number; +} + +interface Alert { + level: 'warning' | 'critical'; + instance: string; + message: string; +} + +export default function NetworkAlertPanel({ data, height = 300 }: NetworkAlertPanelProps) { + const alerts: Alert[] = []; + + [...data.receive, ...data.transmit].forEach((inst) => { + const direction = data.receive.includes(inst) ? 'RX' : 'TX'; + const label = `${direction} ${inst.instance || 'total'}`; + + inst.peaks.peaks.forEach((peak) => { + alerts.push({ + level: 'warning', + instance: label, + message: `${formatTimestamp(peak.startTime)} ~ ${formatTimestamp(peak.endTime)} 트래픽 급증 (max: ${formatBytesPerSec(peak.maxValue)})`, + }); + }); + }); + + if (alerts.length === 0) { + return ( +
+

특이사항 없음

+
+ ); + } + + return ( +
+
+

주의 구간 ({alerts.length}건)

+
+
    + {alerts.map((alert, idx) => ( +
  • + +
    + {alert.instance} +

    {alert.message}

    +
    +
  • + ))} +
+
+ ); +}