Fix #2: Auslastungsmonitor in Agent-Tab + Monitoring nach CPU/RAM sortiert

This commit is contained in:
2026-06-04 17:00:41 +02:00
parent 67059b551d
commit d584e65226
2 changed files with 125 additions and 13 deletions

View File

@@ -748,6 +748,7 @@ const MonitoringPage = () => {
const [agentFilter, setAgentFilter] = useState('all');
const [expandedAgents, setExpandedAgents] = useState(new Set());
const [expandedHosts, setExpandedHosts] = useState(new Set());
const [agentSort, setAgentSort] = useState('cpu');
const [hostFilter, setHostFilter] = useState('all');
const [hostSearch, setHostSearch] = useState('');
const [proxmoxData, setProxmoxData] = useState(null);
@@ -1186,6 +1187,11 @@ const MonitoringPage = () => {
// ─── Tab: Agents ──────────────────────────────────────────────────────────
const renderAgents = () => {
const isAgentOffline = (a) => {
if (!a.last_checkin) return true;
return Date.now() - new Date(a.last_checkin).getTime() > 5 * 60 * 1000;
};
const filtered = agents.filter(a => {
if (agentSearch && !a.hostname.toLowerCase().includes(agentSearch.toLowerCase()) && !(a.ip_address || '').includes(agentSearch)) return false;
if (agentFilter === 'online' && a.status !== 'online') return false;
@@ -1193,6 +1199,27 @@ const MonitoringPage = () => {
if (agentFilter === 'warn' && warnings(a).length === 0) return false;
return true;
});
const sorted = [...filtered].sort((a, b) => {
const aOffline = isAgentOffline(a);
const bOffline = isAgentOffline(b);
// Offline immer ans Ende
if (aOffline !== bOffline) return aOffline ? 1 : -1;
if (agentSort === 'cpu') {
const av = a.cpu_usage_percent ?? (a.ram_total_gb > 0 ? (a.ram_used_gb / a.ram_total_gb) * 100 : 0);
const bv = b.cpu_usage_percent ?? (b.ram_total_gb > 0 ? (b.ram_used_gb / b.ram_total_gb) * 100 : 0);
return bv - av;
}
if (agentSort === 'ram') {
const av = a.ram_total_gb > 0 ? (a.ram_used_gb / a.ram_total_gb) * 100 : 0;
const bv = b.ram_total_gb > 0 ? (b.ram_used_gb / b.ram_total_gb) * 100 : 0;
return bv - av;
}
if (agentSort === 'name') return (a.hostname || '').localeCompare(b.hostname || '');
if (agentSort === 'seen') return new Date(b.last_checkin || 0) - new Date(a.last_checkin || 0);
return 0;
});
return (
<>
<div style={{ display: 'flex', gap: 10, marginBottom: 16, flexWrap: 'wrap', alignItems: 'center' }}>
@@ -1203,10 +1230,16 @@ const MonitoringPage = () => {
{pill(agentFilter === 'offline', () => setAgentFilter('offline'), 'OFFLINE')}
{pill(agentFilter === 'warn', () => setAgentFilter('warn'), 'WARNUNG')}
</div>
<span style={{ fontSize: 12, color: 'var(--text-muted)', marginLeft: 'auto' }}>{filtered.length} Einträge</span>
<select value={agentSort} onChange={e => setAgentSort(e.target.value)} style={{ padding: '5px 10px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'var(--bg-secondary)', color: 'var(--text-primary)', fontSize: 12, cursor: 'pointer' }}>
<option value="cpu">Sortierung: CPU-Auslastung</option>
<option value="ram">Sortierung: RAM-Auslastung</option>
<option value="name">Sortierung: Name</option>
<option value="seen">Sortierung: Zuletzt gesehen</option>
</select>
<span style={{ fontSize: 12, color: 'var(--text-muted)', marginLeft: 'auto' }}>{sorted.length} Einträge</span>
</div>
{filtered.length === 0
{sorted.length === 0
? <div style={{ textAlign: 'center', padding: 40, color: 'var(--text-muted)' }}>Keine Agents gefunden</div>
: (
/* Checkmk-style service table */
@@ -1221,7 +1254,7 @@ const MonitoringPage = () => {
</tr>
</thead>
<tbody>
{filtered.map(a => {
{sorted.map(a => {
const w = warnings(a), hasErr = w.some(x => x.type === 'error');
const state = a.status === 'offline' ? 'crit' : hasErr ? 'crit' : w.length ? 'warn' : 'ok';
const isExp = expandedAgents.has(a.id);