54 lines
2.0 KiB
HTML
54 lines
2.0 KiB
HTML
{{define "content"}}
|
|
<h2>Логи бота в реальном времени</h2>
|
|
<div id="log-container">
|
|
<div>Подключение к потоку логов...</div>
|
|
</div>
|
|
<script>
|
|
const logContainer = document.getElementById('log-container');
|
|
let eventSource = null;
|
|
|
|
function addLogEntry(entry) {
|
|
const div = document.createElement('div');
|
|
const time = new Date(entry.time).toLocaleTimeString();
|
|
let levelClass = '';
|
|
switch (entry.level) {
|
|
case 'INFO': levelClass = 'color: #4ec9b0;'; break;
|
|
case 'WARN': levelClass = 'color: #dcdcaa;'; break;
|
|
case 'ERROR': levelClass = 'color: #f48771;'; break;
|
|
case 'FATAL': levelClass = 'color: #ff0000; font-weight: bold;'; break;
|
|
default: levelClass = '';
|
|
}
|
|
div.innerHTML = `<span style="color: #888;">[${time}]</span> <span style="${levelClass}">[${entry.level}]</span> ${escapeHtml(entry.message)}`;
|
|
logContainer.appendChild(div);
|
|
logContainer.scrollTop = logContainer.scrollHeight;
|
|
}
|
|
|
|
function escapeHtml(str) {
|
|
if (!str) return '';
|
|
return str.replace(/[&<>]/g, function(m) {
|
|
if (m === '&') return '&';
|
|
if (m === '<') return '<';
|
|
if (m === '>') return '>';
|
|
return m;
|
|
});
|
|
}
|
|
|
|
function connectLogStream() {
|
|
if (eventSource) {
|
|
eventSource.close();
|
|
}
|
|
eventSource = new EventSource('/api/logs/stream');
|
|
eventSource.onmessage = function(event) {
|
|
const entry = JSON.parse(event.data);
|
|
addLogEntry(entry);
|
|
};
|
|
eventSource.onerror = function() {
|
|
logContainer.innerHTML += '<div style="color: red;">⚠️ Потеря соединения, переподключение через 3 секунды...</div>';
|
|
eventSource.close();
|
|
setTimeout(connectLogStream, 3000);
|
|
};
|
|
}
|
|
|
|
connectLogStream();
|
|
</script>
|
|
{{end}} |