resetbutton dashboard + agent
This commit is contained in:
@@ -4043,6 +4043,9 @@ class JTLWAFiAgent:
|
||||
elif event_type == 'command.whois':
|
||||
await self._handle_whois_command(event_data)
|
||||
|
||||
elif event_type == 'command.reset_stats':
|
||||
await self._handle_reset_stats_command(event_data)
|
||||
|
||||
elif event_type == 'log.subscribe':
|
||||
shop = event_data.get('shop')
|
||||
if shop:
|
||||
@@ -4589,6 +4592,41 @@ class JTLWAFiAgent:
|
||||
'error': str(e)
|
||||
})
|
||||
|
||||
async def _handle_reset_stats_command(self, data: Dict[str, Any]):
|
||||
"""Setzt alle In-Memory Caches und Statistiken zurück."""
|
||||
global _ip_info_cache, _whois_cache, _shop_stats_trackers
|
||||
|
||||
command_id = data.get('command_id', 'unknown')
|
||||
|
||||
try:
|
||||
# IP-Info Cache leeren
|
||||
_ip_info_cache.clear()
|
||||
logger.info("IP-Info Cache geleert")
|
||||
|
||||
# WHOIS Cache leeren
|
||||
_whois_cache.clear()
|
||||
logger.info("WHOIS Cache geleert")
|
||||
|
||||
# LiveStats Tracker für alle Shops leeren
|
||||
_shop_stats_trackers.clear()
|
||||
logger.info("LiveStats Tracker geleert")
|
||||
|
||||
await self._send_event('command.result', {
|
||||
'command_id': command_id,
|
||||
'status': 'success',
|
||||
'message': f'Agent {self.hostname}: Alle Caches zurückgesetzt'
|
||||
})
|
||||
|
||||
logger.info("Reset Stats: Alle In-Memory Daten zurückgesetzt")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Reset Stats Fehler: {e}")
|
||||
await self._send_event('command.result', {
|
||||
'command_id': command_id,
|
||||
'status': 'error',
|
||||
'message': str(e)
|
||||
})
|
||||
|
||||
async def _periodic_tasks(self):
|
||||
"""Führt periodische Tasks aus."""
|
||||
while self.running:
|
||||
|
||||
@@ -1277,6 +1277,72 @@ async def get_shop_history_api(domain: str, request: Request):
|
||||
return {"domain": domain, **data}
|
||||
|
||||
|
||||
@app.post("/api/reset-stats")
|
||||
async def reset_stats(request: Request):
|
||||
"""Setzt alle In-Memory Statistiken zurück (Dashboard + alle Agents)."""
|
||||
user = await get_current_user(request)
|
||||
if not user:
|
||||
raise HTTPException(401)
|
||||
|
||||
# 1. Reset-Command an alle verbundenen Agents senden
|
||||
agent_count = 0
|
||||
command_id = f"reset_{int(time.time())}"
|
||||
for agent_id in list(manager.agent_connections.keys()):
|
||||
await manager.send_to_agent(agent_id, {
|
||||
'type': 'command.reset_stats',
|
||||
'data': {'command_id': command_id}
|
||||
})
|
||||
agent_count += 1
|
||||
|
||||
# 2. Dashboard Shops zurücksetzen (Statistiken, History)
|
||||
for shop in store.shops.values():
|
||||
shop.log_entries = 0
|
||||
shop.bot_bans = 0
|
||||
shop.country_bans = 0
|
||||
shop.active_bot_bans = 0
|
||||
shop.active_country_bans = 0
|
||||
shop.banned_bots = []
|
||||
shop.banned_countries = []
|
||||
shop.req_per_min = 0.0
|
||||
shop.unique_ips = 0
|
||||
shop.unique_bots = 0
|
||||
shop.unique_countries = 0
|
||||
shop.top_bots = {}
|
||||
shop.top_ips = []
|
||||
shop.top_countries = {}
|
||||
shop.top_requests = {}
|
||||
shop.human_requests = 0
|
||||
shop.bot_requests = 0
|
||||
shop.human_rpm = 0.0
|
||||
shop.bot_rpm = 0.0
|
||||
shop.history.clear()
|
||||
shop.bot_history.clear()
|
||||
shop.country_history.clear()
|
||||
|
||||
# 3. Agents zurücksetzen (nicht löschen, nur Stats)
|
||||
for agent in store.agents.values():
|
||||
agent.load_1m = 0.0
|
||||
agent.load_5m = 0.0
|
||||
agent.memory_percent = 0.0
|
||||
|
||||
# 4. Broadcast an alle Browser um UI zu aktualisieren
|
||||
await manager.broadcast_to_browsers({
|
||||
'type': 'refresh',
|
||||
'data': {
|
||||
'agents': store.get_all_agents(),
|
||||
'shops': store.get_all_shops(),
|
||||
'stats': {
|
||||
'agents_online': len([a for a in store.agents.values() if a.status == 'online']),
|
||||
'shops_active': len([s for s in store.shops.values() if s.status == 'active']),
|
||||
'total_bans': 0,
|
||||
'total_rpm': 0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return {"success": True, "message": f"Dashboard + {agent_count} Agent(s) zurückgesetzt"}
|
||||
|
||||
|
||||
@app.post("/api/update-dashboard")
|
||||
async def update_dashboard(request: Request):
|
||||
"""Dashboard selbst updaten."""
|
||||
@@ -1629,7 +1695,7 @@ def get_dashboard_html() -> str:
|
||||
<div class="clock" id="clock">--:--:--</div>
|
||||
<div class="connection-status"><div class="status-dot" id="wsStatus"></div><span id="wsStatusText">Verbinde...</span></div>
|
||||
<div style="display:flex;align-items:center;gap:8px"><span style="font-size:12px;color:var(--text-secondary)">Update:</span><select id="updateInterval" onchange="setUpdateInterval(this.value)" style="padding:4px 8px;border-radius:4px;border:1px solid var(--border);background:var(--card-bg);color:var(--text);font-size:12px"><option value="2000">2s</option><option value="5000">5s</option><option value="10000" selected>10s</option><option value="15000">15s</option></select></div><div style="display:flex;align-items:center;gap:6px;padding:4px 8px;border-radius:4px;border:1px solid var(--border);background:var(--card-bg)"><label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:12px;color:var(--text-secondary)" title="OPcache nach Aktivierung/Deaktivierung leeren"><input type="checkbox" id="autoFpmRestart" checked style="margin:0"><span>FPM-Restart</span></label></div>
|
||||
<div class="update-dropdown" style="position:relative"><button class="btn-header" onclick="toggleUpdateDropdown()" id="updateDropdownBtn">🔄 v3.1</button><div id="updateDropdownMenu" style="display:none;position:absolute;right:0;top:100%;margin-top:4px;background:var(--card-bg);border:1px solid var(--border);border-radius:8px;padding:8px 0;min-width:200px;z-index:1000;box-shadow:0 4px 12px rgba(0,0,0,0.3)"><button onclick="updateDashboard()" style="display:block;width:100%;text-align:left;padding:8px 16px;border:none;background:none;color:var(--text);cursor:pointer;font-size:13px" onmouseover="this.style.background='var(--bg)'" onmouseout="this.style.background='none'">📊 Dashboard updaten</button><button onclick="updateAgents()" style="display:block;width:100%;text-align:left;padding:8px 16px;border:none;background:none;color:var(--text);cursor:pointer;font-size:13px" onmouseover="this.style.background='var(--bg)'" onmouseout="this.style.background='none'">🖥️ Alle Agents updaten (<span id="agentCountDropdown">0</span>)</button></div></div>
|
||||
<button class="btn-header" onclick="resetStats()" title="Alle Statistiken zurücksetzen">🗑️ Reset</button><div class="update-dropdown" style="position:relative"><button class="btn-header" onclick="toggleUpdateDropdown()" id="updateDropdownBtn">🔄 v3.1</button><div id="updateDropdownMenu" style="display:none;position:absolute;right:0;top:100%;margin-top:4px;background:var(--card-bg);border:1px solid var(--border);border-radius:8px;padding:8px 0;min-width:200px;z-index:1000;box-shadow:0 4px 12px rgba(0,0,0,0.3)"><button onclick="updateDashboard()" style="display:block;width:100%;text-align:left;padding:8px 16px;border:none;background:none;color:var(--text);cursor:pointer;font-size:13px" onmouseover="this.style.background='var(--bg)'" onmouseout="this.style.background='none'">📊 Dashboard updaten</button><button onclick="updateAgents()" style="display:block;width:100%;text-align:left;padding:8px 16px;border:none;background:none;color:var(--text);cursor:pointer;font-size:13px" onmouseover="this.style.background='var(--bg)'" onmouseout="this.style.background='none'">🖥️ Alle Agents updaten (<span id="agentCountDropdown">0</span>)</button></div></div>
|
||||
<div class="notification-dropdown" style="position:relative"><button class="btn-header" onclick="toggleNotificationDropdown()" id="notificationBtn" title="Benachrichtigungen">🔔<span class="notification-badge" id="notificationBadge" style="display:none">0</span></button><div id="notificationDropdown" style="display:none;position:absolute;right:0;top:100%;margin-top:4px;background:#1a1a2e;border:1px solid rgba(255,255,255,0.15);border-radius:8px;min-width:350px;max-width:450px;z-index:1000;box-shadow:0 4px 20px rgba(0,0,0,0.5)"><div style="display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid rgba(255,255,255,0.1);background:#1e1e32"><span style="font-weight:600;font-size:14px">📜 Benachrichtigungen</span><button onclick="clearNotifications()" style="background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:12px" title="Alle löschen">🗑️ Leeren</button></div><div id="notificationList" style="max-height:400px;overflow-y:auto;background:#1a1a2e"></div><div id="notificationEmpty" style="padding:24px;text-align:center;color:var(--text-secondary);font-size:13px;background:#1a1a2e">Keine Benachrichtigungen</div></div></div>
|
||||
<div style="display:flex;gap:8px"><button class="btn-header" onclick="openPasswordModal()">🔑</button><a href="/logout" class="btn-header">Abmelden</a></div>
|
||||
</div>
|
||||
@@ -1805,6 +1871,7 @@ def get_dashboard_html() -> str:
|
||||
document.addEventListener('click',e=>{const dd=document.querySelector('.update-dropdown');if(dd&&!dd.contains(e.target)){document.getElementById('updateDropdownMenu').style.display='none';}});
|
||||
async function updateDashboard(){document.getElementById('updateDropdownMenu').style.display='none';if(!confirm('Dashboard aktualisieren? Das Dashboard wird nach dem Update neu gestartet.'))return;toast('Dashboard wird aktualisiert...','info');try{const r=await fetch('/api/update-dashboard',{method:'POST'});const d=await r.json();if(d.success){toast(d.message,'success');setTimeout(()=>location.reload(),3000);}else{toast(d.error,'error');}}catch(e){toast('Update fehlgeschlagen: '+e,'error');}}
|
||||
async function updateAgents(){document.getElementById('updateDropdownMenu').style.display='none';const cnt=Object.values(agents).filter(a=>a.status==='online').length;if(cnt===0){toast('Keine Agents online','warning');return;}if(!confirm(cnt+' Agent(s) aktualisieren? Die Agents werden nach dem Update neu gestartet.'))return;toast('Agents werden aktualisiert...','info');try{const r=await fetch('/api/update-agents',{method:'POST'});const d=await r.json();if(d.success){toast(d.message,'success');}else{toast(d.error,'error');}}catch(e){toast('Update fehlgeschlagen: '+e,'error');}}
|
||||
async function resetStats(){if(!confirm('Alle Statistiken zurücksetzen?\\n\\nDas löscht:\\n- Alle Shop-Statistiken\\n- Alle History-Graphen\\n- Alle Top-Listen\\n\\nDie Bans und Whitelists bleiben erhalten.'))return;toast('Statistiken werden zurückgesetzt...','info');try{const r=await fetch('/api/reset-stats',{method:'POST'});const d=await r.json();if(d.success){toast(d.message,'success');}else{toast(d.error||'Fehler','error');}}catch(e){toast('Reset fehlgeschlagen: '+e,'error');}}
|
||||
// Server Detail Modal Functions
|
||||
function openServerDetailModal(agentId){currentDetailServer=agentId;const a=agents[agentId];if(!a)return;renderServerDetail();document.getElementById('serverDetailModal').classList.add('open');startServerHistoryUpdate();}
|
||||
function getServerShops(agentId){return Object.values(shops).filter(s=>s.agent_id===agentId);}
|
||||
|
||||
Reference in New Issue
Block a user