// Инициализация при загрузке страницы document.addEventListener('DOMContentLoaded', function () { // Устанавливаем время последнего обновления updateLastUpdateTime(); // Добавляем подсветку логов highlightLogs(); }); // Обновление времени последнего обновления function updateLastUpdateTime() { const now = new Date(); const timeString = now.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); const dateString = now.toLocaleDateString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric' }); document.getElementById('lastUpdateTime').textContent = `${dateString} ${timeString}`; } // Подсветка логов function highlightLogs() { const logsContainer = document.getElementById('logsContainer'); if (!logsContainer) return; const pre = logsContainer.querySelector('pre'); if (!pre) return; let content = pre.innerHTML; // Обработка строкового символа content = content.replace(/\x1B\[[0-9;]*m/g, ''); // Подсветка уровней логирования content = content.replace(/\|\sINFO\s\|/g, '| INFO |'); content = content.replace(/\|\sWARNING\s\|/g, '| WARNING |'); content = content.replace(/\|\sERROR\s\|/g, '| ERROR |'); // Подсветка дат и времени content = content.replace(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/g, '$1'); // Подсветка IP адресов content = content.replace(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g, '$1'); // Подсветка HTTP методов content = content.replace(/(GET|POST|PUT|DELETE|PATCH) (\S+)/g, '$1 $2'); // Подсветка кодов состояний content = content.replace( /"\s(\d{3})\s-/g, (match, code) => { let cls = 'text-secondary'; if (code >= 200 && code < 300) cls = 'text-success'; else if (code >= 400 && code < 500) cls = 'text-warning'; else if (code >= 500) cls = 'text-danger'; return `" ${code} -`; } ); // Подсветка статических файлов content = content.replace( /(\/static\/[^\s"]+)/g, '$1' ); pre.innerHTML = content; } // Переключение видимости логов function toggleLogs() { const logsBody = document.getElementById('logsBody'); const toggleBtn = document.querySelector('.card-header .bi-chevron-down, .card-header .bi-chevron-up'); const logsDescription = document.getElementById('logs_description'); if (logsBody.classList.contains('d-none')) { logsBody.classList.remove('d-none'); toggleBtn.classList.remove('bi-chevron-down'); toggleBtn.classList.add('bi-chevron-up'); logsDescription.classList.remove('d-none'); refreshLogs(); } else { logsBody.classList.add('d-none'); logsDescription.classList.add('d-none'); toggleBtn.classList.remove('bi-chevron-up'); toggleBtn.classList.add('bi-chevron-down'); } } // Обновление логов async function refreshLogs() { try { const logsContainer = document.getElementById('logsContainer'); if (!logsContainer) return; const pre = logsContainer.querySelector('pre'); if (!pre) return; // Показываем индикатор загрузки pre.innerHTML = `
Загрузка логов...

Загрузка логов...

`; // Имитация загрузки логов (в реальном приложении здесь будет fetch запрос) const response = await fetch('/', { method: 'POST', }); const data = await response.json(); pre.innerHTML = data.logs; highlightLogs(); } catch (error) { console.error('Ошибка при обновлении логов:', error); } }