/**
* System Health Panel Component
*
* Real-time system monitoring dashboard showing:
* - CPU usage
* - Memory usage
* - Disk usage
* - Database health
* - Recent activity metrics
*/
import React, { useState, useEffect, useCallback } from 'react';
import {
Activity, Cpu, HardDrive, Database, Server, RefreshCw,
CheckCircle, AlertTriangle, XCircle, Wifi, Clock, Users,
Zap, TrendingUp, BarChart3
} from 'lucide-react';
import { getToken } from '../../services/api';
const API_BASE = import.meta.env.VITE_API_URL || '';
// Status indicator component
const StatusIndicator = ({ status }) => {
const getStatusConfig = () => {
switch (status) {
case 'healthy':
case 'connected':
return { icon: CheckCircle, color: '#10b981', label: 'Healthy' };
case 'warning':
case 'degraded':
return { icon: AlertTriangle, color: '#f59e0b', label: 'Warning' };
case 'critical':
case 'error':
case 'disconnected':
return { icon: XCircle, color: '#ef4444', label: 'Critical' };
default:
return { icon: Activity, color: '#6b7280', label: 'Unknown' };
}
};
const { icon: Icon, color, label } = getStatusConfig();
return (
{label}
);
};
// Metric Card Component
const MetricCard = ({ icon: Icon, title, value, unit, percentage, status, description }) => {
const getBarColor = (pct) => {
if (pct < 60) return '#10b981';
if (pct < 80) return '#f59e0b';
return '#ef4444';
};
return (
{title}
{value}
{unit && {unit}}
{percentage !== undefined && (
)}
{description &&
{description}
}
);
};
// Realtime Stats Row
const RealtimeStats = ({ metrics }) => {
if (!metrics) return null;
return (
{metrics.requests_per_hour || 0}
Requests/hr
{metrics.errors_per_hour || 0}
Errors/hr
{metrics.active_users || 0}
Active Users
);
};
function SystemHealthPanel() {
const [health, setHealth] = useState(null);
const [realtime, setRealtime] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [lastUpdate, setLastUpdate] = useState(null);
const [autoRefresh, setAutoRefresh] = useState(true);
// Fetch full health data
const fetchHealth = useCallback(async () => {
setLoading(true);
setError(null);
try {
const token = getToken();
const response = await fetch(`${API_BASE}/api/admin/health`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) throw new Error('Failed to fetch health data');
const data = await response.json();
if (data.success) {
setHealth(data.health);
setLastUpdate(new Date());
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, []);
// Fetch lightweight realtime metrics
const fetchRealtime = useCallback(async () => {
try {
const token = getToken();
const response = await fetch(`${API_BASE}/api/admin/health/realtime`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
if (data.success) {
setRealtime(data.metrics);
setLastUpdate(new Date());
}
}
} catch (err) {
console.error('Realtime fetch error:', err);
}
}, []);
// Initial fetch
useEffect(() => {
fetchHealth();
}, [fetchHealth]);
// Auto-refresh realtime metrics every 5 seconds
useEffect(() => {
if (!autoRefresh) return;
const interval = setInterval(fetchRealtime, 5000);
return () => clearInterval(interval);
}, [autoRefresh, fetchRealtime]);
if (loading) {
return (
);
}
if (error) {
return (
);
}
const cpu = health?.cpu || {};
const memory = health?.memory || {};
const disk = health?.disk || {};
const database = health?.database || {};
const overallStatus = realtime?.overall_status || health?.overall_status || 'unknown';
return (
{/* Header */}
{/* Realtime Stats */}
{/* Metric Cards */}
{/* Database Stats */}
{database.table_stats && (
Database Tables
{Object.entries(database.table_stats).map(([table, count]) => (
{table}
{count.toLocaleString()} rows
))}
)}
{/* Process Info */}
{health?.process && (
Process Info
Process Memory
{health.process.memory_mb?.toFixed(1)} MB
CPU Usage
{health.process.cpu_percent?.toFixed(1)}%
Threads
{health.process.threads}
Open Files
{health.process.open_files}
)}
);
}
export default SystemHealthPanel;