document.addEventListener('DOMContentLoaded', () => { const logTableContainer = document.getElementById('log-table-container'); const logCountSpan = document.getElementById('log-count'); const levelRadios = document.querySelectorAll('input[name="log-level"]'); const sinceFilter = document.getElementById('since-filter'); const applyFiltersButton = document.getElementById('apply-filters'); const togglePollingButton = document.getElementById('toggle-polling'); const pollingStatusSpan = document.getElementById('polling-status'); const POLLING_INTERVAL_MS = 5000; const serviceUuid = logTableContainer.dataset.serviceUuid; // Get service UUID from data attribute let currentLevel = ''; let currentSince = ''; let pollingIntervalId = null; let isPollingActive = true; // Start active by default // Function to update the UI elements related to polling status function updatePollingStatusUI() { if (isPollingActive) { togglePollingButton.textContent = 'Pause Auto-Refresh'; pollingStatusSpan.textContent = `Auto-refresh: ON (every ${POLLING_INTERVAL_MS / 1000} seconds)`; } else { togglePollingButton.textContent = 'Resume Auto-Refresh'; pollingStatusSpan.textContent = 'Auto-refresh: OFF (paused)'; } } // Function to start polling function startPolling() { if (pollingIntervalId) { clearInterval(pollingIntervalId); // Clear any existing interval to prevent duplicates } isPollingActive = true; fetchLogs(); // Fetch immediately when starting/resuming pollingIntervalId = setInterval(fetchLogs, POLLING_INTERVAL_MS); updatePollingStatusUI(); } // Function to stop polling function stopPolling() { isPollingActive = false; clearInterval(pollingIntervalId); pollingIntervalId = null; updatePollingStatusUI(); } async function fetchLogs() { console.log('Fetching logs with params:', { level: currentLevel, since: currentSince }); try { const params = new URLSearchParams({ format: 'json', limit: '100' }); if (currentLevel) params.append('level', currentLevel); if (currentSince) params.append('since', currentSince); // Use window.API_BASE_PATH for dynamic base URL const url = `${window.API_BASE_PATH}/${serviceUuid}/logs?${params.toString()}`; console.log('Fetch URL:', url); const response = await fetch(url); console.log('Response status:', response.status); console.log('Response Content-Type:', response.headers.get('Content-Type')); if (!response.ok) { const errorText = await response.text(); console.error('Raw response text on error:', errorText.substring(0, 500) + (errorText.length > 500 ? '...' : '')); if (response.status === 404) { console.error(`404 Not Found: Service UUID mismatch. Current page UUID: ${serviceUuid}. Server UUID might have changed. Please hard refresh the page.`); logTableContainer.innerHTML = `
`; } else { // Log the status code to help debug console.error(`HTTP error! status: ${response.status} - ${errorText}`); logTableContainer.innerHTML = ` `; } stopPolling(); // Stop polling on error return; } // Attempt to parse JSON. This is where the error would occur if the content is HTML. const data = await response.json(); console.log('Received logs:', data.logs.length); renderLogTable(data.logs); logCountSpan.textContent = data.log_count; } catch (error) { console.error("Error fetching logs (JSON parsing or other):", error); logTableContainer.innerHTML = ' '; stopPolling(); // Stop polling on error } } function renderLogTable(logs) { console.log('Rendering logs:', logs.length); logTableContainer.innerHTML = ''; // Clear existing content before rendering if (logs.length === 0) { logTableContainer.innerHTML = ' '; return; } const table = document.createElement('table'); table.classList.add('log-table'); const thead = document.createElement('thead'); const headerRow = document.createElement('tr'); const headers = [ { key: 'timestamp', label: 'Timestamp' }, { key: 'level', label: 'Level' }, { key: 'message', label: 'Message' }, { key: 'extra', label: 'Extra' } ]; headers.forEach(header => { const th = document.createElement('th'); th.textContent = header.label; th.dataset.key = header.key; th.classList.add('sortable'); th.addEventListener('click', () => sortTable(header.key)); headerRow.appendChild(th); }); thead.appendChild(headerRow); table.appendChild(thead); const tbody = document.createElement('tbody'); logs.forEach(log => { const row = document.createElement('tr'); row.innerHTML = `