diff --git a/dashboard/server.js b/dashboard/server.js index 19996e8..a05c532 100644 --- a/dashboard/server.js +++ b/dashboard/server.js @@ -490,12 +490,29 @@ app.get('/api/f2b/poll', (req, res) => { }); // ── Routes: Nginx log viewer ────────────────────────────────────────────────── -app.get('/logs/:ip', (req, res) => { +app.get('/logs/:ip', async (req, res) => { const ip = req.params.ip; - const logs = ipLogs.get(ip) || []; const hist = banHistory.get(ip); const esc = s => String(s).replace(/&/g,'&').replace(//g,'>'); + let logs = ipLogs.get(ip) || []; + + // If no logs in memory, grep nginx logs directly + if (logs.length === 0) { + try { + const files = fs.readdirSync(LOG_DIR) + .filter(f => f.startsWith('proxy-host-') && f.endsWith('_access.log')) + .map(f => path.join(LOG_DIR, f)); + + const ipEscaped = ip.replace(/\./g, '\\.'); + const grepCmd = `grep -h "\\[Client ${ipEscaped}\\]" ${files.join(' ')} 2>/dev/null || true`; + const output = await run(grepCmd); + logs = output.trim().split('\n').filter(l => l.trim()).slice(-500); // last 500 lines + } catch (e) { + logs = [`[Error reading logs: ${e.message}]`]; + } + } + let badge = ''; if (hist) badge = `
Entries in current scan window: ${logs.length}
-${logs.map(esc).join('\n') || '(no entries — run a scan first)'}
+ Entries found: ${logs.length}
+${logs.map(esc).join('\n') || '(no entries found)'}