This commit is contained in:
Mateusz Gruszczyński
2025-11-04 08:59:16 +01:00
parent 9949e34d68
commit 04acb4ac21

View File

@@ -1,5 +1,6 @@
/**
* HAProxy Logs Management with Security Alerts
* Fixed pagination
*/
document.addEventListener('DOMContentLoaded', function() {
@@ -26,6 +27,7 @@ document.addEventListener('DOMContentLoaded', function() {
// Event Listeners
searchFilter.addEventListener('keyup', debounce(function() {
console.log('[Logs] Search changed');
currentPage = 1;
loadLogsWithPage();
}, 300));
@@ -48,6 +50,7 @@ document.addEventListener('DOMContentLoaded', function() {
});
clearFilterBtn.addEventListener('click', function() {
console.log('[Logs] Clear filters');
searchFilter.value = '';
excludePhrases = [];
excludeFilter.value = '';
@@ -57,41 +60,45 @@ document.addEventListener('DOMContentLoaded', function() {
});
perPageSelect.addEventListener('change', function() {
console.log(`[Logs] Per page changed to ${this.value}`);
perPage = parseInt(this.value);
currentPage = 1;
applyFilters();
loadLogsWithPage();
});
refreshBtn.addEventListener('click', function() {
console.log('[Logs] Refresh clicked');
searchFilter.value = '';
excludePhrases = [];
excludeFilter.value = '';
updateExcludeUI();
currentPage = 1;
loadLogs();
loadLogsWithPage();
});
prevBtn.addEventListener('click', function() {
if (currentPage > 1) {
console.log(`[Logs] Prev button: page ${currentPage} -> ${currentPage - 1}`);
currentPage--;
applyFilters();
loadLogsWithPage();
}
});
nextBtn.addEventListener('click', function() {
const filtered = getFilteredLogs();
const totalPages = Math.ceil(filtered.length / perPage);
const totalPages = parseInt(document.getElementById('total_pages').textContent);
if (currentPage < totalPages) {
console.log(`[Logs] Next button: page ${currentPage} -> ${currentPage + 1}`);
currentPage++;
applyFilters();
loadLogsWithPage();
}
});
loadAllBtn.addEventListener('click', function() {
perPage = totalLogs;
console.log('[Logs] Load all clicked');
perPage = totalLogs > 500 ? 500 : totalLogs;
currentPage = 1;
perPageSelect.value = totalLogs;
applyFilters();
perPageSelect.value = perPage;
loadLogsWithPage();
});
/**
@@ -105,19 +112,13 @@ document.addEventListener('DOMContentLoaded', function() {
};
}
/**
* Load initial logs from API
*/
function loadLogs() {
logsContainer.innerHTML = '<tr><td class="text-center text-muted py-4">Loading logs...</td></tr>';
loadLogsWithPage();
}
/**
* Load logs with pagination from API
*/
function loadLogsWithPage() {
console.log(`[Logs] Loading page ${currentPage}, per_page ${perPage}`);
console.log(`[Logs] loadLogsWithPage: page=${currentPage}, per_page=${perPage}, search="${searchFilter.value.trim()}", exclude=${excludePhrases.length}`);
logsContainer.innerHTML = '<tr><td class="text-center text-muted py-4">Loading logs...</td></tr>';
fetch('/api/logs', {
method: 'POST',
@@ -131,6 +132,8 @@ document.addEventListener('DOMContentLoaded', function() {
})
.then(r => r.json())
.then(data => {
console.log('[Logs] API Response:', data);
if (data.success) {
allLoadedLogs = data.logs;
loadedSpan.textContent = data.loaded_count;
@@ -144,62 +147,21 @@ document.addEventListener('DOMContentLoaded', function() {
renderLogs(data.logs);
// Update button states
prevBtn.disabled = currentPage === 1;
nextBtn.disabled = !data.has_more;
console.log(`[Logs] Page ${data.page}/${totalPages}, ${data.logs.length} logs`, flush=true);
console.log(`[Logs] Updated: page ${data.page}/${totalPages}, has_more=${data.has_more}, prev_disabled=${prevBtn.disabled}, next_disabled=${nextBtn.disabled}`);
} else {
showError(data.error);
}
})
.catch(e => {
console.error('Error:', e);
showError('Failed to load logs');
console.error('[Logs] Error:', e);
showError('Failed to load logs: ' + e.message);
});
}
/**
* Get filtered logs (for local filtering)
*/
function getFilteredLogs() {
let filtered = allLoadedLogs;
// Apply search filter
if (searchFilter.value.trim()) {
const query = searchFilter.value.toLowerCase();
filtered = filtered.filter(log => {
const text = `${log.timestamp} ${log.ip_address} ${log.http_method} ${log.requested_url} ${log.frontend} ${log.backend}`.toLowerCase();
return text.includes(query);
});
}
// Apply exclude phrases
if (excludePhrases.length > 0) {
filtered = filtered.filter(log => {
const text = `${log.timestamp} ${log.ip_address} ${log.message}`;
return !excludePhrases.some(phrase => text.includes(phrase));
});
}
return filtered;
}
/**
* Apply local filters only
*/
function applyFilters() {
const filtered = getFilteredLogs();
renderLogs(filtered);
const totalPages = Math.ceil(filtered.length / perPage) || 1;
totalPagesSpan.textContent = totalPages;
currentPageSpan.textContent = currentPage;
matchSpan.textContent = filtered.length;
prevBtn.disabled = currentPage === 1;
nextBtn.disabled = (currentPage * perPage) >= filtered.length;
}
/**
* Render logs as table rows
*/
@@ -279,6 +241,7 @@ document.addEventListener('DOMContentLoaded', function() {
* Remove exclude phrase
*/
window.removeExcludePhrase = function(idx) {
console.log(`[Logs] Remove exclude phrase at index ${idx}`);
excludePhrases.splice(idx, 1);
updateExcludeUI();
currentPage = 1;
@@ -300,5 +263,7 @@ document.addEventListener('DOMContentLoaded', function() {
return (text || '').replace(/[&<>"']/g, m => map[m]);
}
loadLogs();
// Initial load
console.log('[Logs] Initial load');
loadLogsWithPage();
});