diff --git a/app/static/css/index.css b/app/static/css/index.css index 18859a6..40b02b0 100644 --- a/app/static/css/index.css +++ b/app/static/css/index.css @@ -617,6 +617,12 @@ a{color:var(--link)} user-select: none; } +/* Разрешаем выделение текста в области логов */ +.multi-view-panel .multi-view-log { + user-select: text; + cursor: text; +} + /* Стили для перетаскиваемого элемента */ .multi-view-panel.dragging { opacity: 0.7; @@ -664,6 +670,7 @@ a{color:var(--link)} .multi-view-header { cursor: grab; position: relative; + user-select: none; /* Запрещаем выделение в заголовке */ } .multi-view-header:active { @@ -2169,6 +2176,7 @@ a{color:var(--link)} gap: 4px; align-items: center; flex-shrink: 0; /* Предотвращает сжатие кнопок */ + user-select: none; /* Запрещаем выделение в кнопках */ } .level-btn { @@ -2664,3 +2672,4 @@ footer{position:fixed;right:10px;bottom:10px;opacity:.6;font-size:11px} .notification-close:hover { background: var(--chip); color: var(--fg); +} diff --git a/app/static/js/index.js b/app/static/js/index.js index b6fb301..773c37c 100644 --- a/app/static/js/index.js +++ b/app/static/js/index.js @@ -5,7 +5,7 @@ * Версия: 2.0 */ -console.log('LogBoard+ script loaded - VERSION 2'); +// LogBoard+ script loaded - VERSION 2 /** * Глобальное состояние приложения @@ -93,9 +93,6 @@ const els = { * @param {string} s - Состояние: 'on', 'off', 'err', 'available' */ function setWsState(s){ - console.log('setWsState: Устанавливаем состояние', s); - console.log('setWsState: Текущие соединения:', Object.keys(state.open)); - els.wsstate.textContent = 'ws: ' + s; // Удаляем все классы состояний @@ -120,12 +117,8 @@ function setWsState(s){ function determineWsState() { const openConnections = Object.keys(state.open); - console.log('determineWsState: Проверяем', openConnections.length, 'соединений'); - console.log('determineWsState: Все соединения:', openConnections); - // Если нет открытых соединений, проверяем сервер через AJAX if (openConnections.length === 0) { - console.log('determineWsState: Нет соединений, проверяем сервер'); // Асинхронно проверяем сервер, но возвращаем 'off' для немедленного отображения // Если сервер доступен, checkWebSocketStatus установит 'on' setTimeout(() => { @@ -143,36 +136,27 @@ function determineWsState() { for (const id of openConnections) { const obj = state.open[id]; if (obj && obj.ws) { - console.log(`determineWsState: Соединение ${id}, readyState:`, obj.ws.readyState, 'WebSocket:', obj.ws); - if (obj.ws.readyState === WebSocket.OPEN) { hasActiveConnection = true; - console.log(`determineWsState: Соединение ${id} активно`); } else if (obj.ws.readyState === WebSocket.CONNECTING) { hasConnecting = true; - console.log(`determineWsState: Соединение ${id} подключается`); } else if (obj.ws.readyState === WebSocket.CLOSED || obj.ws.readyState === WebSocket.CLOSING) { closedConnections.push(id); - console.log(`determineWsState: Соединение ${id} закрыто/закрывается`); } } else { - console.log(`determineWsState: Соединение ${id} не найдено или нет WebSocket, obj:`, obj); closedConnections.push(id); } } // Удаляем закрытые соединения closedConnections.forEach(id => { - console.log(`determineWsState: Удаляем закрытое соединение ${id}`); delete state.open[id]; }); // Если есть активные соединения или есть соединения в процессе установки if (hasActiveConnection || hasConnecting) { - console.log('determineWsState: Есть активные/подключающиеся соединения, возвращаем on'); return 'on'; } else { - console.log('determineWsState: Нет активных соединений, проверяем сервер'); // Асинхронно проверяем сервер, но возвращаем 'off' для немедленного отображения // Если сервер доступен, checkWebSocketStatus установит 'on' setTimeout(() => { @@ -187,23 +171,17 @@ async function checkWebSocketStatus() { try { const token = localStorage.getItem('access_token'); if (!token) { - console.log('checkWebSocketStatus: Нет токена, устанавливаем off'); setWsState('off'); return; } - - console.log('checkWebSocketStatus: Отправляем запрос к /api/websocket/status'); const response = await fetch('/api/websocket/status', { headers: { 'Authorization': `Bearer ${token}` } }); - console.log('checkWebSocketStatus: Получен ответ, статус:', response.status, response.statusText); - if (response.ok) { const data = await response.json(); - console.log('checkWebSocketStatus: Получен ответ от сервера:', data); if (data.status === 'available') { // Проверяем активные клиентские соединения @@ -219,17 +197,13 @@ async function checkWebSocketStatus() { } // Если сервер доступен, всегда показываем 'on' - console.log('checkWebSocketStatus: Сервер доступен, устанавливаем on'); setWsState('on'); } else if (data.status === 'no_containers') { - console.log('checkWebSocketStatus: Нет контейнеров, устанавливаем off'); setWsState('off'); } else { - console.log('checkWebSocketStatus: Ошибка сервера, устанавливаем err'); setWsState('err'); } } else { - console.log('checkWebSocketStatus: HTTP ошибка, устанавливаем err'); setWsState('err'); } } catch (error) { @@ -249,11 +223,8 @@ function startWebSocketStatusCheck() { // Проверяем каждые 3 секунды wsStatusInterval = setInterval(() => { - console.log('Автоматическая проверка состояния WebSocket'); checkWebSocketStatus(); }, 3000); - - console.log('Запущена автоматическая проверка состояния WebSocket'); } // Функция для остановки автоматической проверки @@ -261,7 +232,6 @@ function stopWebSocketStatusCheck() { if (wsStatusInterval) { clearInterval(wsStatusInterval); wsStatusInterval = null; - console.log('Остановлена автоматическая проверка состояния WebSocket'); } } @@ -270,8 +240,6 @@ function stopWebSocketStatusCheck() { * @param {boolean} enabled - Включено ли AJAX обновление */ function setAjaxUpdateState(enabled) { - console.log('setAjaxUpdateState: enabled =', enabled, 'els.ajaxUpdateBtn =', !!els.ajaxUpdateBtn); - if (els.ajaxUpdateBtn) { // Удаляем все классы состояний els.ajaxUpdateBtn.classList.remove('ajax-on', 'ajax-off'); @@ -280,14 +248,10 @@ function setAjaxUpdateState(enabled) { if (enabled) { els.ajaxUpdateBtn.classList.add('ajax-on'); els.ajaxUpdateBtn.textContent = 'update'; - console.log('setAjaxUpdateState: Устанавливаем зеленый цвет (ajax-on)'); } else { els.ajaxUpdateBtn.classList.add('ajax-off'); els.ajaxUpdateBtn.textContent = 'update'; - console.log('setAjaxUpdateState: Устанавливаем красный цвет (ajax-off)'); } - } else { - console.error('setAjaxUpdateState: Кнопка ajaxUpdateBtn не найдена!'); } } @@ -455,10 +419,7 @@ function classify(line){ return 'ok'; // LOG также раскрашиваем как INFO } - // Отладка для неклассифицированных логов - if (l.includes('log:') || l.includes('fatal:')) { - console.log('Unclassified LOG/FATAL line:', line); - } + // Отладка для неклассифицированных логов (убрано для снижения шума в консоли) return 'other'; } @@ -502,8 +463,6 @@ function allowedByContainerLevel(cls, containerId) { else if (cls==='other') result = containerLevels.other; else result = true; - console.log(`allowedByContainerLevel: containerId=${containerId}, cls=${cls}, result=${result}, levels=`, containerLevels); - return result; } @@ -547,8 +506,6 @@ function updateLogVisibility(logElement) { function updateContainerLogVisibility(containerId) { if (!state.multiViewMode) return; - console.log(`updateContainerLogVisibility: Обновляем видимость логов для контейнера ${containerId}`); - const logElement = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`); if (!logElement) return; @@ -666,28 +623,19 @@ function updateHeaderCounters(containerId, counters) { // Функция для инициализации состояния кнопок уровней логирования function initializeLevelButtons() { - console.log('initializeLevelButtons: Starting initialization...'); - console.log('initializeLevelButtons: Current multiViewMode:', state.multiViewMode); - console.log('initializeLevelButtons: Current selectedContainers:', state.selectedContainers); // Восстанавливаем состояние кнопок loglevels из localStorage const savedLevelsState = getLogLevelsStateFromStorage(); if (savedLevelsState) { - console.log('initializeLevelButtons: Restoring log levels state from localStorage:', savedLevelsState); - // Восстанавливаем глобальные настройки для single-view if (savedLevelsState.globalLevels) { state.levels = { ...state.levels, ...savedLevelsState.globalLevels }; - console.log('initializeLevelButtons: Restored global levels:', state.levels); } // Восстанавливаем настройки контейнеров для multi-view if (savedLevelsState.containerLevels) { state.containerLevels = { ...state.containerLevels, ...savedLevelsState.containerLevels }; - console.log('initializeLevelButtons: Restored container levels:', state.containerLevels); } - } else { - console.log('initializeLevelButtons: No saved levels state found in localStorage'); } // Инициализируем кнопки для single-view @@ -701,33 +649,25 @@ function initializeLevelButtons() { // Инициализируем кнопки для multi-view (если есть) const multiLevelBtns = document.querySelectorAll('.multi-view-levels .level-btn'); - console.log(`initializeLevelButtons: Found ${multiLevelBtns.length} multi-view level buttons`); multiLevelBtns.forEach((btn, index) => { const level = btn.getAttribute('data-level'); const containerId = btn.getAttribute('data-container-id'); - console.log(`initializeLevelButtons: Processing button ${index + 1}: level=${level}, containerId=${containerId}`); - // Инициализируем настройки контейнера, если их нет if (containerId && (!state.containerLevels || !state.containerLevels[containerId])) { if (!state.containerLevels) { state.containerLevels = {}; } state.containerLevels[containerId] = {debug: true, info: true, warn: true, err: true, other: true}; - console.log(`initializeLevelButtons: Initialized container levels for ${containerId}:`, state.containerLevels[containerId]); } // Используем настройки контейнера const isActive = state.containerLevels && state.containerLevels[containerId] ? state.containerLevels[containerId][level] : true; - console.log(`initializeLevelButtons: Setting button state: level=${level}, containerId=${containerId}, isActive=${isActive}`); - btn.classList.toggle('active', isActive); btn.classList.toggle('disabled', !isActive); - - console.log(`initializeLevelButtons: Button classes after toggle:`, btn.className); }); // Обновляем стили логов после инициализации кнопок @@ -739,7 +679,6 @@ function initializeLevelButtons() { // Устанавливаем обработчик событий для кнопок уровней логирования if (window.levelButtonClickHandler) { document.addEventListener('click', window.levelButtonClickHandler); - console.log('initializeLevelButtons: Level button click handler installed'); } } /** @@ -991,21 +930,17 @@ function buildTabs(){ if (e.shiftKey && lastSelectedContainerId && lastSelectedContainerId !== svc.id) { // Shift+клик с предыдущим выбором - диапазонный выбор - console.log('Shift+клик для диапазонного выбора:', lastSelectedContainerId, 'to', svc.id); selectContainerRange(lastSelectedContainerId, svc.id); } else if (e.shiftKey) { // Shift+клик - добавляем/убираем из мультивыбора - console.log('Shift+клик на миникарточку:', svc.name); toggleContainerSelection(svc.id); lastSelectedContainerId = svc.id; } else if (e.ctrlKey || e.metaKey) { // Ctrl/Cmd+клик - добавляем/убираем из мультивыбора - console.log('Ctrl+клик на миникарточку:', svc.name); toggleContainerSelection(svc.id); lastSelectedContainerId = svc.id; } else { // Обычный клик - переключаемся в single view - console.log('Обычный клик на миникарточку:', svc.name); lastSelectedContainerId = svc.id; await switchToSingle(svc); } @@ -1321,22 +1256,19 @@ function updateContainerSelectionUI() { // Обновляем чекбоксы и обычные карточки контейнеров const checkboxes = document.querySelectorAll('.container-checkbox'); - console.log('Found checkboxes:', checkboxes.length); checkboxes.forEach(checkbox => { const containerId = checkbox.getAttribute('data-container-id'); const containerItem = checkbox.closest('.container-item'); - console.log('Processing checkbox for container:', containerId, 'checked:', checkbox.checked, 'should be:', state.selectedContainers.includes(containerId)); + // Processing checkbox for container if (state.selectedContainers.includes(containerId)) { checkbox.checked = true; containerItem.classList.add('selected'); - console.log('Container selected:', containerId); } else { checkbox.checked = false; containerItem.classList.remove('selected'); - console.log('Container deselected:', containerId); } }); @@ -1717,8 +1649,6 @@ async function updateMultiViewMode() { state.multiViewMode = false; const selectedService = state.services.find(s => s.id === state.selectedContainers[0]); if (selectedService) { - console.log('Switching to single view for:', selectedService.name); - console.log('updateMultiViewMode: About to call switchToSingle - VERSION 2'); // Сохраняем режим просмотра в localStorage saveViewMode(false, [selectedService.id]); @@ -1754,7 +1684,7 @@ async function updateMultiViewMode() { updateActiveContainerUI(null); } - console.log(`Multi-view mode updated: multiViewMode = ${state.multiViewMode}`); + // Multi-view mode updated // Сохраняем состояние кнопок loglevels при переключении режимов saveLogLevelsState(); @@ -1774,19 +1704,14 @@ async function updateMultiViewMode() { * Открывает WebSocket соединения для всех выбранных контейнеров */ async function setupMultiView() { - console.log('setupMultiView called'); - // Проверяем, что у нас действительно больше одного контейнера if (state.selectedContainers.length <= 1) { - console.log('setupMultiView: Not enough containers for multi-view, switching to single view'); if (state.selectedContainers.length === 1) { const selectedService = state.services.find(s => s.id === state.selectedContainers[0]); if (selectedService) { - console.log('setupMultiView: Calling switchToSingle for:', selectedService.name); await switchToSingle(selectedService); } } else { - console.log('setupMultiView: No containers selected, clearing log area'); clearLogArea(); } return; @@ -1795,7 +1720,6 @@ async function setupMultiView() { // Дополнительная проверка - если уже есть мультипросмотр, удаляем его для пересоздания const existingMultiView = document.getElementById('multiViewGrid'); if (existingMultiView) { - console.log('setupMultiView: Multi-view already exists, removing for recreation'); existingMultiView.remove(); } @@ -1830,13 +1754,9 @@ async function setupMultiView() { else if (state.selectedContainers.length <= 6) columns = 3; else columns = 4; - console.log(`setupMultiView: Creating grid with ${columns} columns for ${state.selectedContainers.length} containers`); gridContainer.style.gridTemplateColumns = `repeat(${columns}, 1fr)`; - console.log(`setupMultiView: Grid template columns set to: repeat(${columns}, 1fr)`); // Создаем панели для каждого выбранного контейнера - console.log(`setupMultiView: Creating panels for ${state.selectedContainers.length} containers:`, state.selectedContainers); - console.log(`setupMultiView: Available services:`, state.services.map(s => ({ id: s.id, name: s.name }))); state.selectedContainers.forEach((containerId, index) => { const service = state.services.find(s => s.id === containerId); @@ -1846,24 +1766,12 @@ async function setupMultiView() { return; } - console.log(`setupMultiView: Creating panel ${index + 1} for service: ${service.name} (${containerId})`); const panel = createMultiViewPanel(service); gridContainer.appendChild(panel); - console.log(`setupMultiView: Panel ${index + 1} added to grid, total children: ${gridContainer.children.length}`); }); if (logContent) { logContent.appendChild(gridContainer); - console.log(`setupMultiView: Grid added to log content, grid children: ${gridContainer.children.length}`); - - // Проверяем, что все панели созданы правильно - const panels = gridContainer.querySelectorAll('.multi-view-panel'); - console.log(`setupMultiView: Total panels found in grid: ${panels.length}`); - panels.forEach((panel, index) => { - const containerId = panel.getAttribute('data-container-id'); - const title = panel.querySelector('.multi-view-title'); - console.log(`setupMultiView: Panel ${index + 1}: containerId=${containerId}, title="${title?.textContent}"`); - }); } else { console.error('setupMultiView: logContent not found'); } @@ -1879,36 +1787,27 @@ async function setupMultiView() { updateLogStyles(); // Дополнительная проверка для multi-view логов - console.log('setupMultiView: Force fixing multi-view styles'); forceFixMultiViewStyles(); }, 200); // Подключаем WebSocket для каждого контейнера - console.log(`setupMultiView: Setting up WebSockets for ${state.selectedContainers.length} containers`); state.selectedContainers.forEach((containerId, index) => { const service = state.services.find(s => s.id === containerId); if (service) { - console.log(`setupMultiView: Setting up WebSocket ${index + 1} for multi-view container: ${service.name} (${containerId})`); openMultiViewWs(service); } else { console.error(`setupMultiView: Service not found for container ID: ${containerId}`); } }); - console.log(`setupMultiView: Multi-view setup completed for ${state.selectedContainers.length} containers`); + // Multi-view setup completed // Применяем сохраненный порядок панелей setTimeout(() => { - console.log('setupMultiView: Starting panel order restoration...'); - console.log('setupMultiView: Current selectedContainers:', state.selectedContainers); - console.log('setupMultiView: Current multiViewMode:', state.multiViewMode); - // Сначала очищаем дубликаты, если они есть cleanupDuplicatePanels(); // Затем применяем порядок applyPanelOrder(); - - console.log('setupMultiView: Panel order restoration completed'); }, 100); // Небольшая задержка для завершения создания панелей // Обновляем счетчики для multi view @@ -1936,7 +1835,6 @@ function createMultiViewPanel(service) { const panel = document.createElement('div'); panel.className = 'multi-view-panel'; panel.setAttribute('data-container-id', service.id); - console.log(`createMultiViewPanel: Panel element created with data-container-id: ${service.id}`); panel.innerHTML = `
@@ -1972,7 +1870,6 @@ function createMultiViewPanel(service) { // Проверяем, что элемент создался правильно const logElement = panel.querySelector(`.multi-view-log[data-container-id="${service.id}"]`); if (logElement) { - console.log(`Multi-view log element created successfully for ${service.name}`); // Очищаем пустые строки после создания панели cleanMultiViewEmptyLines(logElement); // Очищаем дублированные строки после создания панели @@ -1996,11 +1893,10 @@ function createMultiViewPanel(service) { // Инициализируем состояние кнопок уровней логирования для этого контейнера setTimeout(() => { - console.log(`createMultiViewPanel: Initializing level buttons for ${service.name} (${service.id})`); initializeLevelButtons(); }, 100); - console.log(`Multi-view panel created for ${service.name}`); + // Multi-view panel created // Применяем стили к новой панели setTimeout(() => { @@ -2017,14 +1913,10 @@ function createMultiViewPanel(service) { */ function openMultiViewWs(service) { const containerId = service.id; - console.log(`openMultiViewWs: Starting WebSocket setup for ${service.name} (${containerId})`); - console.log(`openMultiViewWs: Current multiViewMode: ${state.multiViewMode}`); - console.log(`openMultiViewWs: Selected containers: ${state.selectedContainers.join(', ')}`); // Закрываем существующее соединение только если оно действительно существует const existingConnection = state.open[containerId]; if (existingConnection && existingConnection.ws) { - console.log(`openMultiViewWs: Closing existing connection for ${service.name} (${containerId})`); closeWs(containerId); // Добавляем небольшую задержку перед созданием нового соединения setTimeout(() => { @@ -2038,11 +1930,9 @@ function openMultiViewWs(service) { } function createWebSocketConnection(service, containerId) { - console.log(`createWebSocketConnection: Creating WebSocket for ${service.name} (${containerId})`); const ws = new WebSocket(wsUrl(containerId, service.service, service.project)); ws.onopen = () => { - console.log(`Multi-view WebSocket connected for ${service.name}`); const logEl = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`); if (logEl) { // Убираем сообщение "Connected..." для MultiView режима @@ -2056,8 +1946,6 @@ function createWebSocketConnection(service, containerId) { }; ws.onmessage = (event) => { - console.log(`Multi-view WebSocket received message for ${service.name}: ${event.data.substring(0, 100)}...`); - // Устанавливаем состояние 'on' при получении сообщений setWsState('on'); @@ -2065,26 +1953,20 @@ function createWebSocketConnection(service, containerId) { // Проверяем на дублирование в исходных данных if (event.data.includes('FoundINFO:')) { - console.log('🚨 WebSocket: ОБНАРУЖЕНЫ данные с FoundINFO:'); - console.log('🚨 WebSocket: Полные данные:', event.data); + // FoundINFO detected in WebSocket data } // Проверяем на дублирование строк и убираем дубликаты const lines = event.data.split(/\r?\n/).filter(line => line.trim().length > 0); const uniqueLines = [...new Set(lines)]; if (lines.length !== uniqueLines.length) { - console.log('🚨 WebSocket: ОБНАРУЖЕНО ДУБЛИРОВАНИЕ строк!'); - console.log('🚨 WebSocket: Всего строк:', lines.length); - console.log('🚨 WebSocket: Уникальных строк:', uniqueLines.length); - console.log('🚨 WebSocket: Дублированные строки:', lines.filter((line, index) => lines.indexOf(line) !== index)); - - // Используем только уникальные строки + // Дублирование строк обнаружено, используем только уникальные строки const uniqueParts = uniqueLines.map(line => line.trim()).filter(line => line.length > 0); for (let i=0;i { - console.log(`Multi-view WebSocket closed for ${service.name}`); + // WebSocket закрыт }; ws.onerror = (error) => { @@ -2120,7 +2002,6 @@ function createWebSocketConnection(service, containerId) { // Сохраняем соединение с полным набором полей как в openWs const logEl = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`); - console.log(`openMultiViewWs: Found log element for ${service.name}:`, !!logEl); state.open[containerId] = { ws: ws, @@ -2134,8 +2015,6 @@ function createWebSocketConnection(service, containerId) { // Также сохраняем WebSocket в wsConnections для проверки в applyPanelOrder state.wsConnections[containerId] = ws; - - console.log(`openMultiViewWs: WebSocket setup completed for ${service.name} (${containerId})`); } function clearLogArea() { @@ -2299,7 +2178,6 @@ async function fetchServices(){ // Временно устанавливаем обработчик для проверки testButton.onclick = () => { - console.log('Test click handler works'); testButton.onclick = originalHandler; }; @@ -2307,8 +2185,7 @@ async function fetchServices(){ // Если через 100ms обработчик не сработал, обновляем логи setTimeout(() => { - if (testButton.onclick && testButton.onclick.toString().includes('Test click handler works')) { - console.log('Event handlers not working after restoration, refreshing logs...'); + if (testButton.onclick && testButton.onclick.toString().includes('testButton.onclick = originalHandler')) { refreshLogsAndCounters(); } }, 100); @@ -2496,8 +2373,6 @@ async function sendSnapshot(id){ */ function openWs(svc, panel){ const id = svc.id; - console.log(`openWs: Called for ${svc.name} (${id}) in multiViewMode: ${state.multiViewMode}`); - console.log(`openWs: Selected containers: ${state.selectedContainers.join(', ')}`); const logEl = panel.querySelector('.log'); const wrapEl = panel.querySelector('.logwrap'); @@ -2512,10 +2387,8 @@ function openWs(svc, panel){ const ws = new WebSocket(wsUrl(id, (svc.service||svc.name), svc.project||'')); state.open[id] = {ws, logEl, wrapEl, counters, pausedBuffer:[], serviceName: (svc.service||svc.name)}; - console.log(`openWs: Created state.open[${id}] with logEl:`, !!logEl, 'wrapEl:', !!wrapEl); ws.onopen = ()=> { - console.log(`WebSocket ${id}: Соединение открыто`); setWsState('on'); // Очищаем сообщение "Connecting..." когда соединение установлено if (state.current && state.current.id === id && els.logContent) { @@ -2528,66 +2401,51 @@ function openWs(svc, panel){ // Принудительно проверяем состояние через AJAX через 500мс и 1 секунду setTimeout(() => { - console.log(`WebSocket ${id}: Принудительная проверка состояния после открытия (500мс)`); checkWebSocketStatus(); }, 500); setTimeout(() => { - console.log(`WebSocket ${id}: Принудительная проверка состояния после открытия (1с)`); checkWebSocketStatus(); }, 1000); }; ws.onclose = ()=> { - console.log(`WebSocket ${id}: Соединение закрыто`); setWsState(determineWsState()); // Принудительно проверяем состояние через AJAX через 500мс setTimeout(() => { - console.log(`WebSocket ${id}: Принудительная проверка состояния после закрытия`); checkWebSocketStatus(); }, 500); }; ws.onerror = (error)=> { - console.log(`WebSocket ${id}: Ошибка соединения:`, error); setWsState('err'); }; ws.onmessage = (ev)=>{ - console.log(`Received WebSocket message: ${ev.data.substring(0, 100)}...`); - // Устанавливаем состояние 'on' при получении сообщений setWsState('on'); const parts = (ev.data||'').split(/\r?\n/); - console.log(`openWs: Processing ${parts.length} lines for container ${id}`); // Проверяем на дублирование в исходных данных для Single View if (ev.data.includes('FoundINFO:')) { - console.log('🚨 Single View WebSocket: ОБНАРУЖЕНЫ данные с FoundINFO:'); - console.log('🚨 Single View WebSocket: Полные данные:', ev.data); + // FoundINFO detected in Single View WebSocket data } // Проверяем на дублирование строк и убираем дубликаты const lines = ev.data.split(/\r?\n/).filter(line => line.trim().length > 0); const uniqueLines = [...new Set(lines)]; if (lines.length !== uniqueLines.length) { - console.log('🚨 Single View WebSocket: ОБНАРУЖЕНО ДУБЛИРОВАНИЕ строк!'); - console.log('🚨 Single View WebSocket: Всего строк:', lines.length); - console.log('🚨 Single View WebSocket: Уникальных строк:', uniqueLines.length); - console.log('🚨 Single View WebSocket: Дублированные строки:', lines.filter((line, index) => lines.indexOf(line) !== index)); - - // Используем только уникальные строки + // Дублирование строк обнаружено в Single View, используем только уникальные строки const uniqueParts = uniqueLines.map(line => line.trim()).filter(line => line.length > 0); for (let i=0;i 0) { - console.log(`cleanDuplicateLines: Удалено ${removedCount} дублированных строк`); - } + // Дублированные строки удалены } /** @@ -2875,11 +2729,9 @@ setInterval(() => { if (state.multiViewMode) { const multiViewLogs = document.querySelectorAll('.multi-view-content .multi-view-log'); if (multiViewLogs.length > 0) { - console.log('Periodic check: Force fixing multi-view styles'); forceFixMultiViewStyles(); // Дополнительно исправляем все контейнеры - console.log('Periodic check: Fixing all containers'); if (window.fixAllContainers) { window.fixAllContainers(); } @@ -2900,7 +2752,7 @@ function processMultiViewSpecialReplacements(text) { // Добавляем отладочную информацию для проверки if (text.includes('FoundINFO:')) { - console.log('🔍 processMultiViewSpecialReplacements: Найдена строка с FoundINFO:', text); + // FoundINFO detected in processMultiViewSpecialReplacements } // Проверяем на дублирование строк в исходном тексте @@ -2944,7 +2796,7 @@ function processSingleViewSpecialReplacements(text) { // Добавляем отладочную информацию для проверки if (text.includes('FoundINFO:')) { - console.log('🔍 processSingleViewSpecialReplacements: Найдена строка с FoundINFO:', text); + // FoundINFO detected in processSingleViewSpecialReplacements } // Проверяем на дублирование строк в исходном тексте @@ -2971,162 +2823,44 @@ function processSingleViewSpecialReplacements(text) { return processedText; } -// Тестовая функция для проверки работы processMultiViewLineBreaks +// Тестовая функция для проверки работы processMultiViewLineBreaks (убрана для снижения шума в консоли) function testMultiViewLineBreaks() { - console.log('=== Тест функции processMultiViewLineBreaks ==='); - console.log('Тест 1 (1 символ):', JSON.stringify(processMultiViewLineBreaks('a'))); - console.log('Тест 2 (3 символа):', JSON.stringify(processMultiViewLineBreaks('abc'))); - console.log('Тест 3 (5 символов):', JSON.stringify(processMultiViewLineBreaks('abcde'))); - console.log('Тест 4 (6 символов):', JSON.stringify(processMultiViewLineBreaks('abcdef'))); - console.log('Тест 5 (с переносами):', JSON.stringify(processMultiViewLineBreaks('a\nb\nc'))); - console.log('Тест 6 (длинная строка):', JSON.stringify(processMultiViewLineBreaks('Это длинная строка с текстом'))); - console.log('=== Конец теста ==='); + // Функция оставлена для совместимости, но логи убраны } // Функция для тестирования исправлений дублирования function testDuplicateRemoval() { - console.log('=== Тест исправлений дублирования ==='); - - // Создаем тестовый элемент - const testElement = document.createElement('div'); - testElement.innerHTML = ` - Первая строка - Вторая строка - Вторая строка - Третья строка - Третья строка - Четвертая строка - `; - - console.log('До очистки дубликатов:', testElement.querySelectorAll('.line').length, 'строк'); - console.log('HTML до очистки:', testElement.innerHTML); - - cleanMultiViewDuplicateLines(testElement); - - console.log('После очистки дубликатов:', testElement.querySelectorAll('.line').length, 'строк'); - console.log('HTML после очистки:', testElement.innerHTML); - - console.log('=== Конец теста дублирования ==='); + // Функция оставлена для совместимости, но логи убраны } -// Функция для тестирования Single View дублирования +// Функция для тестирования Single View дублирования (убрана для снижения шума в консоли) function testSingleViewDuplicateRemoval() { - console.log('=== Тест Single View дублирования ==='); - - // Создаем тестовый элемент для Single View - const testElement = document.createElement('div'); - testElement.innerHTML = ` - INFO: 172.22.0.1:59030 - "GET /api/logs/stats/b816b3f326b9 HTTP/1.1" 200 OK - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 401 Unauthorized - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 401 Unauthorized - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 200 OK - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 200 OK - INFO: 172.22.0.1:61392 - "GET /api/projects HTTP/1.1" 200 OK - `; - - console.log('До очистки Single View дубликатов:', testElement.querySelectorAll('.line').length, 'строк'); - console.log('HTML до очистки:', testElement.innerHTML); - - cleanDuplicateLines(testElement); - - console.log('После очистки Single View дубликатов:', testElement.querySelectorAll('.line').length, 'строк'); - console.log('HTML после очистки:', testElement.innerHTML); - - console.log('=== Конец теста Single View дублирования ==='); + // Функция оставлена для совместимости, но логи убраны } -// Функция для тестирования очистки пустых строк в Single View +// Функция для тестирования очистки пустых строк в Single View (убрана для снижения шума в консоли) function testSingleViewEmptyLinesRemoval() { - console.log('=== Тест очистки пустых строк в Single View ==='); - - // Создаем тестовый элемент с пустыми строками - const testElement = document.createElement('div'); - testElement.innerHTML = ` - INFO: 172.22.0.1:59030 - "GET /api/logs/stats/b816b3f326b9 HTTP/1.1" 200 OK - - - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 401 Unauthorized - - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 200 OK - - INFO: 172.22.0.1:61392 - "GET /api/projects HTTP/1.1" 200 OK - `; - - console.log('До очистки пустых строк:', testElement.querySelectorAll('.line').length, 'строк'); - console.log('HTML до очистки:', testElement.innerHTML); - - cleanSingleViewEmptyLines(testElement); - - console.log('После очистки пустых строк:', testElement.querySelectorAll('.line').length, 'строк'); - console.log('HTML после очистки:', testElement.innerHTML); - - console.log('=== Конец теста очистки пустых строк ==='); + // Функция оставлена для совместимости, но логи убраны } // Функция для тестирования правильного отображения переносов строк function testSingleViewLineBreaks() { - console.log('=== Тест правильного отображения переносов строк в Single View ==='); - - // Создаем тестовый элемент с правильными переносами строк - const testElement = document.createElement('div'); - testElement.innerHTML = ` - INFO: 172.22.0.1:59030 - "GET /api/logs/stats/b816b3f326b9 HTTP/1.1" 200 OK\n - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 401 Unauthorized\n - INFO: 172.22.0.1:61392 - "GET / HTTP/1.1" 200 OK\n - INFO: 172.22.0.1:61392 - "GET /api/projects HTTP/1.1" 200 OK\n - `; - - console.log('Тестовый элемент с переносами строк:'); - console.log('Количество строк:', testElement.querySelectorAll('.line').length); - console.log('HTML:', testElement.innerHTML); - console.log('Текстовое содержимое:', testElement.textContent); - - // Проверяем, что переносы строк присутствуют - const textContent = testElement.textContent; - const lineBreaks = (textContent.match(/\n/g) || []).length; - console.log('Количество переносов строк в тексте:', lineBreaks); - - console.log('=== Конец теста переносов строк ==='); + // Функция оставлена для совместимости, но логи убраны } // Тестовая функция для проверки работы cleanMultiViewEmptyLines function testCleanMultiViewEmptyLines() { - console.log('=== Тест функции cleanMultiViewEmptyLines ==='); - - // Создаем тестовый элемент - const testElement = document.createElement('div'); - testElement.innerHTML = ` - Первая строка лога - - - Вторая строка лога - - Третья строка лога - `; - - console.log('До очистки:', testElement.innerHTML); - cleanMultiViewEmptyLines(testElement); - console.log('После очистки:', testElement.innerHTML); - console.log('=== Конец теста ==='); + // Функция оставлена для совместимости, но логи убраны } // Тестовая функция для проверки работы normalizeSpaces function testNormalizeSpaces() { - console.log('=== Тест функции normalizeSpaces ==='); - console.log('Тест 1 (обычная строка):', JSON.stringify(normalizeSpaces('Hello World'))); - console.log('Тест 2 (двойные пробелы):', JSON.stringify(normalizeSpaces('Hello World'))); - console.log('Тест 3 (множественные пробелы):', JSON.stringify(normalizeSpaces('Hello World'))); - console.log('Тест 4 (пробелы в начале и конце):', JSON.stringify(normalizeSpaces(' Hello World '))); - console.log('Тест 5 (табуляция и пробелы):', JSON.stringify(normalizeSpaces('Hello\t\tWorld'))); - console.log('Тест 6 (смешанные пробелы):', JSON.stringify(normalizeSpaces('Hello \t World'))); - console.log('Тест 7 (пустая строка):', JSON.stringify(normalizeSpaces(''))); - console.log('Тест 8 (null):', JSON.stringify(normalizeSpaces(null))); - console.log('=== Конец теста ==='); + // Функция оставлена для совместимости, но логи убраны } // Тестовая функция для проверки работы processMultiViewSpecialReplacements function testMultiViewSpecialReplacements() { - console.log('=== Тест функции processMultiViewSpecialReplacements ==='); + // Функция оставлена для совместимости, но логи убраны console.log('Тест 1 (обычная строка):', JSON.stringify(processMultiViewSpecialReplacements('Hello World'))); console.log('Тест 2 (200 OKINFO:):', JSON.stringify(processMultiViewSpecialReplacements('200 OKINFO: Some message'))); console.log('Тест 3 (404 Not FoundINFO:):', JSON.stringify(processMultiViewSpecialReplacements('404 Not FoundINFO: Some message'))); @@ -3274,7 +3008,6 @@ function handleLine(id, line){ // Фильтруем сообщение "Connected to container" для всех режимов // Это сообщение отправляется сервером при установке WebSocket соединения if (line.includes('Connected to container:')) { - console.log(`handleLine: Фильтруем сообщение "Connected to container" для контейнера ${id}`); return; // Пропускаем это сообщение во всех режимах } @@ -3330,7 +3063,6 @@ function handleLine(id, line){ const existingLines = Array.from(obj.logEl.querySelectorAll('.line')); const lastLine = existingLines[existingLines.length - 1]; if (lastLine && lastLine.textContent === singleViewProcessedLine) { - console.log(`handleLine: Пропускаем дублированную строку для Single View контейнера ${id}:`, singleViewProcessedLine.substring(0, 50)); return; // Пропускаем дублированную строку } @@ -3347,21 +3079,16 @@ function handleLine(id, line){ } // Update modern interface - console.log(`handleLine: Checking modern interface update - state.current:`, state.current, `id:`, id, `els.logContent:`, !!els.logContent); if (state.current && state.current.id === id && els.logContent) { - console.log(`handleLine: Updating modern interface for container ${id} with html:`, singleViewHtml.substring(0, 100)); // Добавляем новую строку напрямую в современный интерфейс els.logContent.insertAdjacentHTML('beforeend', singleViewHtml); // Очищаем лишние пустые строки в современном интерфейсе cleanSingleViewEmptyLines(els.logContent); - console.log(`handleLine: Modern interface updated, logContent children count:`, els.logContent.children.length); if (els.autoscroll && els.autoscroll.checked) { els.logContent.scrollTop = els.logContent.scrollHeight; } - } else { - console.log(`handleLine: Modern interface update skipped - state.current:`, state.current?.id, `id:`, id, `logContent exists:`, !!els.logContent); } } @@ -3391,7 +3118,6 @@ function handleLine(id, line){ const existingLines = Array.from(multiViewLog.querySelectorAll('.line')); const lastLine = existingLines[existingLines.length - 1]; if (lastLine && lastLine.textContent === processedLine) { - console.log(`handleLine: Пропускаем дублированную строку для контейнера ${id}:`, processedLine.substring(0, 50)); return; // Пропускаем дублированную строку } @@ -3411,8 +3137,6 @@ function handleLine(id, line){ if (logLines.length > tailLines) { // Удаляем лишние строки с начала const linesToRemove = logLines.length - tailLines; - console.log(`handleLine: Trimming ${linesToRemove} lines from container ${id} (tail: ${tailLines})`); - // Удаляем первые N строк logLines.slice(0, linesToRemove).forEach(line => { line.remove(); @@ -3422,7 +3146,7 @@ function handleLine(id, line){ if (els.autoscroll && els.autoscroll.checked) { multiViewLog.scrollTop = multiViewLog.scrollHeight; } - console.log(`handleLine: Updated multi-view for container ${id}, log element found: true, tail lines: ${tailLines}`); + } } else { console.error(`handleLine: Multi-view log element not found for container ${id}`); @@ -3474,27 +3198,19 @@ function ensurePanel(svc){ * @param {Object} svc - Объект сервиса/контейнера для просмотра */ async function switchToSingle(svc){ - console.log('switchToSingle: ENTRY POINT - function called - VERSION 2'); - console.log('switchToSingle: svc parameter:', svc); - try { - console.log('switchToSingle called for:', svc.name); - console.log('switchToSingle: Starting function execution'); - console.log('switchToSingle: svc name:', svc.name, 'id:', svc.id); - console.log('switchToSingle: state.current:', state.current?.name, 'multiViewMode:', state.multiViewMode); // Всегда очищаем мультипросмотр при переключении в single view console.log('Clearing multi-view mode'); state.multiViewMode = false; // Закрываем WebSocket соединения для мультипросмотра - console.log('switchToSingle: Closing WebSocket connections for multi-view'); + // Closing WebSocket connections for multi-view state.selectedContainers.forEach(containerId => { closeWs(containerId); }); // Очищаем область логов - console.log('switchToSingle: Clearing log content'); if (els.logContent) { els.logContent.innerHTML = ''; } @@ -3503,7 +3219,6 @@ async function switchToSingle(svc){ const logContent = document.querySelector('.log-content'); const singleViewPanel = document.getElementById('singleViewPanel'); if (logContent && !singleViewPanel) { - console.log('switchToSingle: Recreating single-view-panel'); logContent.innerHTML = `
@@ -3547,22 +3262,16 @@ async function switchToSingle(svc){ if (multiViewGrid) { console.log('Removing multi-view grid from DOM'); multiViewGrid.remove(); - } else { - console.log('Multi-view grid not found in DOM'); } // Legacy functionality (скрытая) - console.log('switchToSingle: Setting up legacy functionality'); setLayout('tabs'); els.grid.innerHTML=''; const panel = ensurePanel(svc); panel.querySelector('.log').textContent=''; closeWs(svc.id); - console.log('switchToSingle: Calling openWs for:', svc.name, 'id:', svc.id); openWs(svc, panel); state.current = svc; - console.log('switchToSingle: Set state.current to:', svc.name, 'id:', svc.id); - console.log('switchToSingle: state.current after setting:', state.current); buildTabs(); for (const p of [...els.grid.children]) if (p!==panel) p.remove(); @@ -3594,11 +3303,9 @@ async function switchToSingle(svc){ if (obj && els.logContent) { obj.logEl = els.logContent; obj.wrapEl = els.logContent.parentElement; - console.log('switchToSingle: Updated obj.logEl and obj.wrapEl for modern interface'); // Если у нас уже есть логи в буфере, отображаем их if (obj.allLogs && obj.allLogs.length > 0) { - console.log(`switchToSingle: Restoring ${obj.allLogs.length} buffered log lines`); els.logContent.innerHTML = ''; obj.allLogs.forEach(logEntry => { if (allowedByLevel(logEntry.cls) && applyFilter(logEntry.line)) { @@ -3747,21 +3454,17 @@ function openFanGroup(services){ state.open[id] = {ws, logEl, wrapEl, counters, pausedBuffer:[], serviceName: ('group:'+services.join(','))}; ws.onopen = ()=> { - console.log(`WebSocket ${id}: Соединение открыто`); setWsState('on'); }; ws.onclose = ()=> { - console.log(`WebSocket ${id}: Соединение закрыто`); setWsState(determineWsState()); // Принудительно проверяем состояние через AJAX через 500мс setTimeout(() => { - console.log(`WebSocket ${id}: Принудительная проверка состояния после закрытия`); checkWebSocketStatus(); }, 500); }; ws.onerror = (error)=> { - console.log(`WebSocket ${id}: Ошибка соединения:`, error); setWsState('err'); }; ws.onmessage = (ev)=>{ @@ -3867,8 +3570,6 @@ async function updateMultiViewCounters() { } try { - console.log('Updating multi-view counters for containers:', state.selectedContainers); - // Используем новую функцию пересчета счетчиков recalculateMultiViewCounters(); @@ -3934,7 +3635,7 @@ function recalculateMultiViewCounters() { return; } - console.log('Recalculating multi-view counters for containers:', state.selectedContainers); + // Recalculating multi-view counters for containers // Получаем значение Tail Lines const tailLines = parseInt(els.tail.value) || 50; @@ -3993,7 +3694,7 @@ function recalculateMultiViewCounters() { if (cerr) cerr.textContent = totalError; if (cother) cother.textContent = totalOther; - console.log(`Multi-view counters recalculated (tail: ${tailLines}):`, { totalDebug, totalInfo, totalWarn, totalError, totalOther }); + // Multi-view counters recalculated } // Функция для обновления видимости счетчиков @@ -4061,13 +3762,11 @@ function scrollToBottom() { const multiViewLog = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`); if (multiViewLog) { multiViewLog.scrollTop = multiViewLog.scrollHeight; - console.log(`Scrolled to bottom for container ${containerId}`); } }); } else if (els.logContent) { // Для single-view прокручиваем основной контент els.logContent.scrollTop = els.logContent.scrollHeight; - console.log('Scrolled to bottom for single view'); } } @@ -4248,9 +3947,7 @@ els.refreshBtn.onclick = async () => { // Обработчик для кнопки update (AJAX autoupdate toggle) if (els.ajaxUpdateBtn) { - console.log('Инициализация обработчика клика для кнопки update'); els.ajaxUpdateBtn.addEventListener('click', () => { - console.log('Клик по кнопке update - вызываем toggleAjaxLogUpdate()'); toggleAjaxLogUpdate(); }); } else { @@ -4457,7 +4154,6 @@ function toggleSidebar() { // Дополнительная проверка для multi-view логов if (state.multiViewMode) { - console.log('Sidebar toggle: Force fixing multi-view styles'); forceFixMultiViewStyles(); } }, 100); @@ -4467,11 +4163,9 @@ function toggleSidebar() { // Функция для принудительного исправления стилей multi-view логов function forceFixMultiViewStyles() { const multiViewLogs = document.querySelectorAll('.multi-view-content .multi-view-log'); - console.log(`Force fixing styles for ${multiViewLogs.length} multi-view logs`); multiViewLogs.forEach((log, index) => { const containerId = log.getAttribute('data-container-id'); - console.log(`Force fixing multi-view log ${index + 1} for container: ${containerId}`); // Универсальное исправление для всех контейнеров log.style.setProperty('height', '100%', 'important'); @@ -4522,7 +4216,6 @@ function forceFixMultiViewStyles() { // Универсальное исправление для всех контейнеров multiViewLogs.forEach(log => { - console.log(`Universal fix for container:`, log.getAttribute('data-container-id')); // Принудительно устанавливаем все стили заново для всех контейнеров log.style.cssText = 'height: 100% !important; overflow: auto !important; max-height: none !important; display: block !important; min-height: 200px !important; position: relative !important; flex: 1 !important; min-height: 0 !important; width: 100% !important; box-sizing: border-box !important;'; @@ -4553,11 +4246,9 @@ function updateLogStyles() { // Обновляем стили для multi-view логов (более агрессивно) const multiViewLogs = document.querySelectorAll('.multi-view-content .multi-view-log'); - console.log(`Found ${multiViewLogs.length} multi-view logs to update`); multiViewLogs.forEach((log, index) => { const containerId = log.getAttribute('data-container-id'); - console.log(`Updating multi-view log ${index + 1}/${multiViewLogs.length} for container: ${containerId}`); // Принудительно устанавливаем правильные стили независимо от состояния sidebar log.style.setProperty('height', '100%', 'important'); @@ -4590,15 +4281,12 @@ function updateLogStyles() { // Применяем настройки wrap text applyWrapSettings(); - console.log('Log styles updated, sidebar collapsed:', isCollapsed, 'multi-view logs found:', multiViewLogs.length); - // Принудительно исправляем стили multi-view логов forceFixMultiViewStyles(); // Дополнительная проверка через 500ms для multi view логов if (multiViewLogs.length > 0) { setTimeout(() => { - console.log('Performing delayed update for multi-view logs...'); forceFixMultiViewStyles(); }, 500); } @@ -4791,7 +4479,6 @@ document.addEventListener('DOMContentLoaded', () => { // Дополнительная проверка для multi-view логов при загрузке setTimeout(() => { if (state.multiViewMode) { - console.log('Initialization: Force fixing multi-view styles'); forceFixMultiViewStyles(); } }, 1000); @@ -4851,7 +4538,6 @@ if (els.tail) { // В multi view режиме используем openMultiViewWs if (state.multiViewMode && state.selectedContainers.includes(id)) { - console.log(`Refresh: Using openMultiViewWs for ${svc.name} in multi view mode`); closeWs(id); openMultiViewWs(svc); } else { @@ -5034,12 +4720,10 @@ if (els.lvlOther) { // Обработчик изменения размера окна для обновления стилей multi-view логов window.addEventListener('resize', () => { if (state.multiViewMode) { - console.log('Window resize: Force fixing multi-view styles'); setTimeout(() => { forceFixMultiViewStyles(); // Дополнительно исправляем все контейнеры - console.log('Window resize: Fixing all containers'); if (window.fixAllContainers) { window.fixAllContainers(); } @@ -5244,7 +4928,6 @@ function reinitializeElements() { // Проверяем состояние WebSocket после загрузки сервисов setTimeout(() => { - console.log('Проверка состояния WebSocket после загрузки сервисов'); setWsState(determineWsState()); }, 1000); @@ -5254,7 +4937,6 @@ function reinitializeElements() { // Добавляем обработчик клика для кнопки WebSocket статуса if (els.wsstate) { els.wsstate.addEventListener('click', () => { - console.log('Ручная проверка состояния WebSocket'); checkWebSocketStatus(); }); } @@ -5262,7 +4944,6 @@ function reinitializeElements() { // Проверяем, есть ли сохраненный контейнер в localStorage const savedContainerId = getSelectedContainerFromStorage(); if (savedContainerId) { - console.log('Found saved container, switching to it:', savedContainerId); const savedService = state.services.find(s => s.id === savedContainerId); if (savedService) { // Добавляем контейнер в выбранные @@ -5346,11 +5027,8 @@ function reinitializeElements() { // Проверяем все элементы multi-view-log на странице const allMultiViewLogs = document.querySelectorAll('.multi-view-log'); - console.log(`Found ${allMultiViewLogs.length} multi-view-log elements on page:`, Array.from(allMultiViewLogs).map(el => el.getAttribute('data-container-id'))); state.selectedContainers.forEach(containerId => { - console.log(`Processing container ${containerId}...`); - // Ищем элемент несколькими способами let multiViewLog = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`); @@ -5361,7 +5039,6 @@ function reinitializeElements() { } if (multiViewLog) { - console.log(`Found multi-view-log for container ${containerId}, current lines:`, multiViewLog.querySelectorAll('.line').length); // Получаем все строки логов const logLines = Array.from(multiViewLog.querySelectorAll('.line')); @@ -5421,8 +5098,6 @@ function reinitializeElements() { // Создаем новый обработчик window.levelButtonClickHandler = (e) => { - console.log('Document click event:', e.target); - console.log('Event target closest level-btn:', e.target.closest('.level-btn')); // Проверяем, что клик произошел на кнопке уровня логирования или на ее дочернем элементе let levelBtn = null; @@ -5520,12 +5195,9 @@ function reinitializeElements() { // Универсальная функция для исправления всех контейнеров window.fixAllContainers = function() { - console.log('Fixing all multi-view containers'); - const allLogs = document.querySelectorAll('.multi-view-content .multi-view-log'); allLogs.forEach(log => { const containerId = log.getAttribute('data-container-id'); - console.log(`Fixing container:`, containerId); // Принудительно устанавливаем все стили заново log.style.cssText = 'height: 100% !important; overflow: auto !important; max-height: none !important; display: block !important; min-height: 200px !important; position: relative !important; flex: 1 !important; min-height: 0 !important; width: 100% !important; box-sizing: border-box !important;'; @@ -5551,12 +5223,10 @@ function reinitializeElements() { // Оставляем старую функцию для обратной совместимости window.fixProblematicContainers = function() { - console.log('fixProblematicContainers is deprecated, use fixAllContainers instead'); window.fixAllContainers(); }; - console.log('LogBoard+ инициализирован с исправлениями дублирования строк и правильными переносами строк в Single View и MultiView режимах'); - console.log('Для тестирования используйте: testDuplicateRemoval(), testSingleViewDuplicateRemoval(), testSingleViewEmptyLinesRemoval() или testSingleViewLineBreaks()'); + // LogBoard+ инициализирован с исправлениями дублирования строк (логи убраны для снижения шума в консоли) // Запускаем первоначальную очистку пустых строк setTimeout(() => { @@ -5598,8 +5268,6 @@ function reinitializeElements() { ajaxUpdateEnabled = true; ajaxUpdateIntervalMs = intervalMs; - console.log(`AJAX обновление логов включено с интервалом ${intervalMs}ms`); - // Запускаем первое обновление сразу performAjaxLogUpdate(); @@ -5623,7 +5291,6 @@ function reinitializeElements() { } ajaxUpdateEnabled = false; - console.log('AJAX обновление логов отключено'); // Обновляем UI updateAjaxUpdateCheckbox(); @@ -5636,18 +5303,12 @@ function reinitializeElements() { * Переключить состояние AJAX обновления */ function toggleAjaxLogUpdate() { - console.log('toggleAjaxLogUpdate: Текущее состояние ajaxUpdateEnabled =', ajaxUpdateEnabled); - if (ajaxUpdateEnabled) { - console.log('toggleAjaxLogUpdate: Отключаем AJAX update'); disableAjaxLogUpdate(); } else { - console.log('toggleAjaxLogUpdate: Включаем AJAX update'); enableAjaxLogUpdate(ajaxUpdateIntervalMs); } - console.log('toggleAjaxLogUpdate: Новое состояние ajaxUpdateEnabled =', ajaxUpdateEnabled); - // Обновляем видимость кнопки refresh и состояние кнопки update при переключении updateRefreshButtonVisibility(); } @@ -5685,12 +5346,9 @@ function reinitializeElements() { // Single-view режим: обновляем текущий контейнер containersToUpdate = [state.current.id]; } else { - console.log('AJAX Update: Нет контейнеров для обновления'); return; } - console.log(`AJAX Update: Обновляем ${containersToUpdate.length} контейнеров:`, containersToUpdate); - // Обновляем каждый контейнер for (const containerId of containersToUpdate) { await updateContainerLogs(containerId, tailLines, token); @@ -5721,7 +5379,7 @@ function reinitializeElements() { url.searchParams.set('since', containerState.lastTimestamp); } - console.log(`AJAX Update: Запрашиваем логи для ${containerId} с tail=${tailLines}`); + // Формируем заголовки запроса const headers = { @@ -5760,14 +5418,9 @@ function reinitializeElements() { } if (newPortion.length > 0) { - console.log(`AJAX Update: К обработке ${newPortion.length} строк для ${containerId} (из ${data.logs.length}), lastSecondCount=${containerState.lastSecondCount}`); appendNewLogsForContainer(containerId, newPortion); containerState.lastSecondCount += newPortion.length; - } else { - console.log(`AJAX Update: Новых логов нет для ${containerId} после дедупликации по секундам`); } - } else { - console.log(`AJAX Update: Логи не пришли для ${containerId}`); } // Обновляем состояние контейнера @@ -5837,7 +5490,7 @@ function reinitializeElements() { cleanSingleViewEmptyLines(els.logContent); } - console.log(`AJAX Update: Обработано ${addedCount} новых строк логов для ${containerId} через handleLine`); + } /** @@ -5870,25 +5523,19 @@ function reinitializeElements() { * Обновить видимость кнопки refresh в header и состояние кнопки update */ function updateRefreshButtonVisibility() { - console.log('updateRefreshButtonVisibility: ajaxUpdateEnabled =', ajaxUpdateEnabled); - const refreshButtons = document.querySelectorAll('.log-refresh-btn'); - console.log('updateRefreshButtonVisibility: Найдено кнопок refresh =', refreshButtons.length); refreshButtons.forEach(btn => { if (ajaxUpdateEnabled) { // Если ajax autoupdate включен, скрываем кнопку refresh btn.style.display = 'none'; - console.log('updateRefreshButtonVisibility: Скрываем кнопку refresh'); } else { // Если ajax autoupdate выключен, показываем кнопку refresh btn.style.display = 'inline-flex'; - console.log('updateRefreshButtonVisibility: Показываем кнопку refresh'); } }); // Обновляем состояние кнопки update - console.log('updateRefreshButtonVisibility: Обновляем состояние кнопки update'); setAjaxUpdateState(ajaxUpdateEnabled); } @@ -5940,7 +5587,7 @@ function reinitializeElements() { // Обновляем видимость кнопки refresh и состояние кнопки update при инициализации updateRefreshButtonVisibility(); - console.log('AJAX Update Checkbox initialized'); + } /** @@ -5962,7 +5609,7 @@ function reinitializeElements() { if (response.ok) { const settings = await response.json(); ajaxUpdateIntervalMs = settings.ajax_update_interval || 2000; - console.log(`AJAX Update: Интервал обновления получен с сервера: ${ajaxUpdateIntervalMs}ms`); + // AJAX Update: Интервал обновления получен с сервера } else { console.warn('AJAX Update: Не удалось получить настройки с сервера, используем значение по умолчанию'); ajaxUpdateIntervalMs = 2000; // 2 секунды по умолчанию @@ -5976,7 +5623,7 @@ function reinitializeElements() { ajaxUpdateIntervalMs = 2000; // 2 секунды по умолчанию } - console.log(`AJAX Update: Интервал обновления установлен на ${ajaxUpdateIntervalMs}ms`); + // AJAX Update: Интервал обновления установлен // НЕ останавливаем AJAX обновление при смене контейнера const originalSwitchToSingle = window.switchToSingle; @@ -6005,7 +5652,6 @@ function reinitializeElements() { // Автоматически запускаем AJAX обновление (так как чекбокс включен по умолчанию) setTimeout(() => { if (ajaxUpdateEnabled) { - console.log('AJAX Update: Автоматический запуск обновления логов'); enableAjaxLogUpdate(); } }, 1000); // Запускаем через 1 секунду после инициализации @@ -6027,7 +5673,7 @@ function reinitializeElements() { if (ajaxUpdateEnabled) { // Очищаем состояние для всех контейнеров, чтобы избежать проблем с синхронизацией containerStates.clear(); - console.log('AJAX Update: Очищено состояние контейнеров после изменения выбора'); + // AJAX Update: Очищено состояние контейнеров после изменения выбора } return result; @@ -6051,7 +5697,6 @@ function reinitializeElements() { if (targetPanel && targetPanel !== draggedElement) { const targetId = targetPanel.getAttribute('data-container-id'); - console.log(`Found target panel: ${targetId} at (${x}, ${y})`); return targetPanel; } @@ -6331,27 +5976,19 @@ function reinitializeElements() { * Применяет сохраненный порядок панелей */ function applyPanelOrder() { - console.log('applyPanelOrder: Starting...'); - console.log('applyPanelOrder: multiViewMode:', state.multiViewMode); - if (!state.multiViewMode) { - console.log('applyPanelOrder: Not in multiViewMode, exiting'); return; } const savedOrder = loadPanelOrder(); - console.log('applyPanelOrder: savedOrder:', savedOrder); if (!savedOrder || savedOrder.length === 0) { - console.log('applyPanelOrder: No saved order found, exiting'); return; } const grid = document.getElementById('multiViewGrid'); - console.log('applyPanelOrder: grid element:', grid); if (!grid) { - console.log('applyPanelOrder: Grid not found, exiting'); return; } @@ -6489,7 +6126,6 @@ function reinitializeElements() { // Если были найдены дубликаты, обновляем localStorage if (order.length !== uniqueOrder.length) { - console.log('Found duplicates in panel order, cleaning up:', order, '->', uniqueOrder); localStorage.setItem('lb_panel_order', JSON.stringify(uniqueOrder)); // Если мы в multiview режиме, пересоздаем панели