fixes
This commit is contained in:
@@ -1,103 +1,107 @@
|
||||
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 filterHideStats = document.getElementById('filter_hide_stats');
|
||||
const resetBtn = document.getElementById('reset_filters');
|
||||
let currentPage = 1;
|
||||
let perPage = 50;
|
||||
let totalLogs = parseInt(document.getElementById('total_count').textContent);
|
||||
let allLogs = [];
|
||||
|
||||
const logsTable = document.getElementById('logs_table');
|
||||
if (!logsTable) return; // Exit if no logs
|
||||
const logsContainer = document.getElementById('logs_container');
|
||||
const perPageSelect = document.getElementById('logs_per_page');
|
||||
const refreshBtn = document.getElementById('refresh_logs_btn');
|
||||
const prevBtn = document.getElementById('prev_btn');
|
||||
const nextBtn = document.getElementById('next_btn');
|
||||
const loadAllBtn = document.getElementById('load_all_btn');
|
||||
const loadedSpan = document.getElementById('loaded_count');
|
||||
const currentPageSpan = document.getElementById('current_page');
|
||||
const totalPagesSpan = document.getElementById('total_pages');
|
||||
|
||||
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;
|
||||
const hideStats = filterHideStats.checked;
|
||||
|
||||
let visibleCount = 0;
|
||||
let threatCount = 0;
|
||||
let count2xx = 0, count4xx = 0, count5xx = 0;
|
||||
const uniqueIps = new Set();
|
||||
|
||||
allRows.forEach(row => {
|
||||
const ip = row.dataset.ip;
|
||||
const status = row.dataset.status;
|
||||
const method = row.dataset.method;
|
||||
const hasThreat = row.dataset.threats === '1';
|
||||
const url = row.querySelector('td:nth-child(4)').textContent.trim();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Hide /stats filter
|
||||
if (hideStats && url.includes('/stats')) {
|
||||
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);
|
||||
filterHideStats.addEventListener('change', applyFilters);
|
||||
|
||||
// Reset button
|
||||
resetBtn.addEventListener('click', function() {
|
||||
filterIp.value = '';
|
||||
filterStatus.value = '';
|
||||
filterMethod.value = '';
|
||||
filterThreats.checked = true;
|
||||
filterHideStats.checked = true;
|
||||
applyFilters();
|
||||
perPageSelect.addEventListener('change', function(e) {
|
||||
perPage = parseInt(e.target.value);
|
||||
currentPage = 1;
|
||||
loadLogs();
|
||||
});
|
||||
|
||||
applyFilters();
|
||||
refreshBtn.addEventListener('click', function() {
|
||||
currentPage = 1;
|
||||
loadLogs();
|
||||
});
|
||||
|
||||
prevBtn.addEventListener('click', function() {
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
loadLogs();
|
||||
}
|
||||
});
|
||||
|
||||
nextBtn.addEventListener('click', function() {
|
||||
const totalPages = Math.ceil(totalLogs / perPage);
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
loadLogs();
|
||||
}
|
||||
});
|
||||
|
||||
loadAllBtn.addEventListener('click', function() {
|
||||
perPage = totalLogs;
|
||||
currentPage = 1;
|
||||
perPageSelect.value = totalLogs;
|
||||
loadLogs();
|
||||
});
|
||||
|
||||
function loadLogs() {
|
||||
fetch('/api/logs', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
page: currentPage,
|
||||
per_page: perPage
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
renderLogs(data.logs);
|
||||
updatePagination(data);
|
||||
console.log(`[Logs] Załadowano page ${data.page}/${Math.ceil(data.total / data.per_page)}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error loading logs:', error);
|
||||
logsContainer.innerHTML = `<tr><td class="alert alert-danger">Błąd załadowania logów</td></tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
function renderLogs(logs) {
|
||||
if (!logs || logs.length === 0) {
|
||||
logsContainer.innerHTML = '<tr><td class="text-center text-muted py-4"><i class="bi bi-inbox"></i> Brak logów</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
logsContainer.innerHTML = logs.map(entry => `
|
||||
<tr>
|
||||
<td>
|
||||
<small style="font-family: monospace; color: #666;">
|
||||
<i class="bi bi-clock text-muted me-1"></i>${entry.timestamp || 'N/A'}<br>
|
||||
<span class="text-muted">${entry.source || 'N/A'}</span><br>
|
||||
<code style="color: #333; word-break: break-all; display: block; margin-top: 4px;">
|
||||
${entry.message || 'N/A'}
|
||||
</code>
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function updatePagination(data) {
|
||||
const totalPages = Math.ceil(data.total / data.per_page);
|
||||
loadedSpan.textContent = data.logs.length;
|
||||
currentPageSpan.textContent = data.page;
|
||||
totalPagesSpan.textContent = totalPages;
|
||||
|
||||
prevBtn.disabled = data.page === 1;
|
||||
nextBtn.disabled = !data.has_more;
|
||||
}
|
||||
|
||||
loadLogs();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user