diff --git a/static/js/logs.js b/static/js/logs.js index 5fe277c..23045ec 100644 --- a/static/js/logs.js +++ b/static/js/logs.js @@ -1,22 +1,92 @@ -document.getElementById('filter_status')?.addEventListener('change', filterLogs); -document.getElementById('filter_threat')?.addEventListener('change', filterLogs); -document.getElementById('filter_method')?.addEventListener('change', filterLogs); -document.getElementById('filter_threats_only')?.addEventListener('change', filterLogs); - -function filterLogs() { - const statusFilter = document.getElementById('filter_status')?.value; - const threatFilter = document.getElementById('filter_threat')?.value; - const methodFilter = document.getElementById('filter_method')?.value; - const threatsOnly = document.getElementById('filter_threats_only')?.checked; +document.addEventListener('DOMContentLoaded', function() { + const filterIp = document.getElementById('filter_ip'); + const filterStatus = document.getElementById('filter_status'); + const filterMethod = document.getElementById('filter_method'); + const filterThreats = document.getElementById('filter_threats'); + const resetBtn = document.getElementById('reset_filters'); - document.querySelectorAll('.log-row').forEach(row => { - let show = true; + const logsTable = document.getElementById('logs_table'); + const allRows = Array.from(document.querySelectorAll('.log-row')); + + // Filter function + function applyFilters() { + const ipValue = filterIp.value.toLowerCase(); + const statusValue = filterStatus.value; + const methodValue = filterMethod.value; + const showThreats = filterThreats.checked; - if (statusFilter && row.dataset.status !== statusFilter) show = false; - if (threatFilter && row.dataset.threat !== threatFilter) show = false; - if (methodFilter && row.dataset.method !== methodFilter) show = false; - if (threatsOnly && row.dataset.threatCount === '0') show = false; + let visibleCount = 0; + let threatCount = 0; + let count2xx = 0, count4xx = 0, count5xx = 0; + const uniqueIps = new Set(); - row.style.display = show ? '' : 'none'; + allRows.forEach(row => { + const ip = row.dataset.ip; + const status = row.dataset.status; + const method = row.dataset.method; + const hasThreat = row.dataset.threats === '1'; + + let show = true; + + // IP filter + if (ipValue && !ip.includes(ipValue)) { + show = false; + } + + // Status filter + if (statusValue) { + const statusStart = statusValue; + if (!status.startsWith(statusStart)) { + show = false; + } + } + + // Method filter + if (methodValue && method !== methodValue) { + show = false; + } + + // Threats filter + if (!showThreats && hasThreat) { + show = false; + } + + row.style.display = show ? '' : 'none'; + + if (show) { + visibleCount++; + if (hasThreat) threatCount++; + if (status.startsWith('2')) count2xx++; + if (status.startsWith('4')) count4xx++; + if (status.startsWith('5')) count5xx++; + uniqueIps.add(ip); + } + }); + + // Update stats + document.getElementById('stat_total').textContent = visibleCount; + document.getElementById('stat_threats').textContent = threatCount; + document.getElementById('stat_2xx').textContent = count2xx; + document.getElementById('stat_4xx').textContent = count4xx; + document.getElementById('stat_5xx').textContent = count5xx; + document.getElementById('stat_ips').textContent = uniqueIps.size; + } + + // Event listeners + filterIp.addEventListener('input', applyFilters); + filterStatus.addEventListener('change', applyFilters); + filterMethod.addEventListener('change', applyFilters); + filterThreats.addEventListener('change', applyFilters); + + // Reset button + resetBtn.addEventListener('click', function() { + filterIp.value = ''; + filterStatus.value = ''; + filterMethod.value = ''; + filterThreats.checked = true; + applyFilters(); }); -} \ No newline at end of file + + // Initial stats + applyFilters(); +}); \ No newline at end of file diff --git a/templates/logs.html b/templates/logs.html index 47a26e0..546f4ae 100644 --- a/templates/logs.html +++ b/templates/logs.html @@ -2,151 +2,165 @@ {% set active_page = "logs" %} -{% block title %}HAProxy • Access Logs{% endblock %} +{% block title %}HAProxy • Logs{% endblock %} -{% block breadcrumb %}Access Logs{% endblock %} +{% block breadcrumb %}Logs{% endblock %} {% block content %}
| Timestamp | -IP Address | -Method | -URL | -Status | -Threats | -
|---|---|---|---|---|---|
| {{ log.timestamp }} | -- {{ log.ip_address }} - | -- {{ log.http_method }} - | -- {{ log.requested_url }} - | -- {{ log.status_code }} - | -- {% if log.is_threat %} - {% for threat in log.threats %} - {{ threat }} - {% endfor %} - {% else %} - — - {% endif %} - | -
| Timestamp | +IP Address | +HTTP Method | +Requested URL | +Status Code | +Alerts | +
|---|---|---|---|---|---|
| {{ entry['timestamp'] }} | ++ {{ entry['ip_address'] }} + | ++ {{ entry['http_method'] }} + | ++ {{ entry['requested_url'] }} + | ++ + {{ entry['status_code'] }} + + | ++ {% if entry['xss_alert'] %} + XSS + {% endif %} + {% if entry['sql_alert'] %} + SQL + {% endif %} + {% if entry['put_method'] %} + PUT + {% endif %} + {% if entry['webshell_alert'] %} + Webshell + {% endif %} + {% if entry['illegal_resource'] %} + 403 + {% endif %} + | +