/** * 系统监控服务 * 处理系统性能指标获取和展示 */ // 日志自动刷新相关变量 let logRefreshTimer = null; let logCountdownTimer = null; let logCurrentInterval = 10; let logFullContent = ''; // 设置自动刷新间隔 function setRefreshInterval() { const select = document.getElementById('logRefreshInterval'); const countdownEl = document.getElementById('logRefreshCountdown'); const secondsEl = document.getElementById('countdownNumber'); if (!select) return; logCurrentInterval = parseInt(select.value) || 10; // 清除之前的定时器 if (logRefreshTimer) { clearInterval(logRefreshTimer); logRefreshTimer = null; } if (logCountdownTimer) { clearInterval(logCountdownTimer); logCountdownTimer = null; } // 如果选择关闭,不显示倒计时 if (select.value === '0') { countdownEl.classList.add('hidden'); return; } // 显示倒计时 countdownEl.classList.remove('hidden'); secondsEl.textContent = logCurrentInterval; // 启动倒计时 let countdown = logCurrentInterval; logCountdownTimer = setInterval(() => { countdown--; if (countdown <= 0) { countdown = logCurrentInterval; } secondsEl.textContent = countdown; }, 1000); // 启动自动刷新 logRefreshTimer = setInterval(() => { if (typeof refreshLogs === 'function') { refreshLogs(); } }, logCurrentInterval * 1000); } // 获取系统性能监控数据 async function fetchSystemMetrics() { try { const response = await fetch(`${window.API_BASE}/health`); const result = await response.json(); if (result.code === 0 && result.data) { const data = result.data; // 更新CPU使用率 const cpuEl = document.getElementById('cpuUsage'); if (cpuEl && data.cpu_percent !== undefined) { cpuEl.textContent = data.cpu_percent; cpuEl.className = data.cpu_percent > 80 ? 'text-red-500 font-medium' : ''; } // 更新内存使用率 const memEl = document.getElementById('memUsage'); if (memEl && data.memory_percent !== undefined) { memEl.textContent = data.memory_percent; memEl.className = data.memory_percent > 80 ? 'text-red-500 font-medium' : ''; } // 更新磁盘使用率 const diskEl = document.getElementById('diskUsage'); if (diskEl && data.disk_percent !== undefined) { diskEl.textContent = data.disk_percent; diskEl.className = data.disk_percent > 80 ? 'text-red-500 font-medium' : ''; } } } catch (error) { console.error('获取系统监控数据失败:', error); } } // 停止日志自动刷新(离开页面时调用) function stopLogAutoRefresh() { if (logRefreshTimer) { clearInterval(logRefreshTimer); logRefreshTimer = null; } if (logCountdownTimer) { clearInterval(logCountdownTimer); logCountdownTimer = null; } } // 刷新日志 function refreshLogs() { if (typeof switchLogTab === 'function') { const currentLogTab = window.currentLogTab || 'system'; if (currentLogTab === 'system') { if (typeof loadLogFiles === 'function' && document.getElementById('logTypeSelect')?.value) { loadSelectedLog(); } else { loadLogFiles(); } } else { loadTrainingLogFiles(); } } else { loadLogFiles(); } // 重置倒计时 const select = document.getElementById('logRefreshInterval'); const secondsEl = document.getElementById('countdownNumber'); if (select && select.value !== '0' && secondsEl) { secondsEl.textContent = logCurrentInterval; } } // 滚动到日志底部 function scrollToLogBottom() { const logContent = document.getElementById('logContent'); if (logContent) { logContent.scrollTop = logContent.scrollHeight; } } // 当前日志类型:system 或 training window.currentLogTab = 'system'; // 切换日志类型标签 function switchLogTab(tab) { window.currentLogTab = tab; const systemTab = document.getElementById('logTabSystem'); const trainingTab = document.getElementById('logTabTraining'); const systemOptions = document.getElementById('systemLogOptions'); const trainingOptions = document.getElementById('trainingLogOptions'); if (tab === 'system') { systemTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors bg-white shadow-sm text-primary'; trainingTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors text-gray-600 hover:text-gray-800'; systemOptions.classList.remove('hidden'); trainingOptions.classList.add('hidden'); loadLogFiles(); } else { trainingTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors bg-white shadow-sm text-primary'; systemTab.className = 'px-4 py-1.5 text-sm rounded-md transition-colors text-gray-600 hover:text-gray-800'; trainingOptions.classList.remove('hidden'); systemOptions.classList.add('hidden'); loadTrainingLogFiles(); } } // 初始化日志查看器 function initLogViewer() { const datePicker = document.getElementById('logDatePicker'); if (datePicker) { const today = new Date().toISOString().split('T')[0]; datePicker.value = today; } // 加载默认日志类型 loadLogFiles(); // 启动自动刷新 setRefreshInterval(); } // 加载训练日志文件列表 async function loadTrainingLogFiles() { const logSelect = document.getElementById('trainingLogSelect'); if (!logSelect) return; logSelect.innerHTML = ''; try { const response = await fetch(`${window.API_BASE}/training-log-files`); const result = await response.json(); if (result.code === 0 && result.data) { logSelect.innerHTML = ''; result.data.forEach(log => { const option = document.createElement('option'); option.value = log.file; option.textContent = `${log.name} (PID: ${log.pid}, ${log.date}, ${log.size})`; logSelect.appendChild(option); }); // 如果有日志文件,自动加载第一个 if (result.data.length > 0) { logSelect.value = result.data[0].file; loadSelectedTrainingLog(); } else { document.getElementById('logContent').textContent = '暂无训练日志'; document.getElementById('logFileInfo').textContent = '无训练日志'; } } else { logSelect.innerHTML = ''; document.getElementById('logContent').textContent = '暂无训练日志'; document.getElementById('logFileInfo').textContent = '无训练日志'; } } catch (error) { console.error('加载训练日志列表失败:', error); logSelect.innerHTML = ''; document.getElementById('logContent').textContent = '加载训练日志列表失败: ' + error.message; } } // 加载选中的训练日志 async function loadSelectedTrainingLog() { const logSelect = document.getElementById('trainingLogSelect'); const logFile = logSelect.value; const logContent = document.getElementById('logContent'); const logFileInfo = document.getElementById('logFileInfo'); if (!logFile) { logContent.textContent = '请选择训练日志'; logFileInfo.textContent = '无训练日志'; return; } logContent.textContent = '加载中...'; logFileInfo.textContent = '加载中...'; try { const response = await fetch(`${window.API_BASE}/training-log-content?file=${encodeURIComponent(logFile)}`); const result = await response.json(); if (result.code === 0 && result.data) { logFullContent = result.data.content || ''; logContent.textContent = logFullContent || '(空日志)'; logFileInfo.textContent = result.data.file + ' (' + result.data.size + ')'; // 清空搜索 document.getElementById('logSearchInput').value = ''; document.getElementById('logMatchCount').textContent = ''; // 滚动到底部 scrollToLogBottom(); } else { logContent.textContent = '加载失败: ' + (result.message || '未知错误'); logFileInfo.textContent = '加载失败'; } } catch (error) { console.error('加载训练日志内容失败:', error); logContent.textContent = '加载失败: ' + error.message; logFileInfo.textContent = '加载失败'; } } // 加载日志文件列表 async function loadLogFiles() { const datePicker = document.getElementById('logDatePicker'); const logTypeSelect = document.getElementById('logTypeSelect'); const selectedDate = datePicker ? datePicker.value : new Date().toISOString().split('T')[0]; if (!logTypeSelect) return; logTypeSelect.innerHTML = ''; try { const response = await fetch(`${window.API_BASE}/log-files?date=${selectedDate}`); const result = await response.json(); if (result.code === 0 && result.data) { logTypeSelect.innerHTML = ''; result.data.forEach(log => { const option = document.createElement('option'); option.value = log.file; option.textContent = log.name + ' (' + log.size + ')'; logTypeSelect.appendChild(option); }); // 如果有日志文件,自动加载第一个 if (result.data.length > 0) { logTypeSelect.value = result.data[0].file; loadSelectedLog(); } else { logTypeSelect.innerHTML = ''; document.getElementById('logContent').textContent = '该日期暂无日志文件'; document.getElementById('logFileInfo').textContent = '无日志文件'; } } else { logTypeSelect.innerHTML = ''; document.getElementById('logContent').textContent = '该日期暂无日志文件'; document.getElementById('logFileInfo').textContent = '无日志文件'; } } catch (error) { console.error('加载日志文件列表失败:', error); logTypeSelect.innerHTML = ''; document.getElementById('logContent').textContent = '加载日志文件列表失败: ' + error.message; } } // 加载选中的日志 async function loadSelectedLog() { const logTypeSelect = document.getElementById('logTypeSelect'); const logFile = logTypeSelect.value; const logContent = document.getElementById('logContent'); const logFileInfo = document.getElementById('logFileInfo'); if (!logFile) { logContent.textContent = '请选择日志文件'; logFileInfo.textContent = '无日志文件'; return; } logContent.textContent = '加载中...'; logFileInfo.textContent = '加载中...'; try { const response = await fetch(`${window.API_BASE}/log-content?file=${encodeURIComponent(logFile)}`); const result = await response.json(); if (result.code === 0) { logFullContent = result.data.content || ''; logContent.textContent = logFullContent || '(空日志)'; logFileInfo.textContent = result.data.file + ' (' + result.data.size + ')'; // 清空搜索框和匹配计数 document.getElementById('logSearchInput').value = ''; document.getElementById('logMatchCount').textContent = ''; // 滚动到最底部 scrollToLogBottom(); } else { logContent.textContent = '加载失败: ' + (result.message || '未知错误'); logFileInfo.textContent = '加载失败'; } } catch (error) { console.error('加载日志内容失败:', error); logContent.textContent = '加载日志内容失败: ' + error.message; logFileInfo.textContent = '加载失败'; } } // 过滤日志内容 function filterLogContent() { const searchInput = document.getElementById('logSearchInput'); const matchCount = document.getElementById('logMatchCount'); const logContent = document.getElementById('logContent'); if (!searchInput || !matchCount || !logContent) return; const keyword = searchInput.value.trim(); if (!keyword) { logContent.textContent = logFullContent || '(空日志)'; matchCount.textContent = ''; scrollToLogBottom(); return; } const lines = logFullContent.split('\n'); const matchingLines = lines.filter(line => line.toLowerCase().includes(keyword.toLowerCase())); if (matchingLines.length > 0) { logContent.textContent = matchingLines.join('\n'); matchCount.textContent = `(${matchingLines.length}条匹配)`; // 滚动到最底部查看最新匹配 scrollToLogBottom(); } else { logContent.textContent = '未找到匹配的日志'; matchCount.textContent = '(0条匹配)'; } } // 清空日志内容显示 function clearLogContent() { document.getElementById('logContent').textContent = '日志内容将在这里显示...'; document.getElementById('logFileInfo').textContent = '请选择日志文件'; const logTypeSelect = document.getElementById('logTypeSelect'); if (logTypeSelect) logTypeSelect.value = ''; document.getElementById('logSearchInput').value = ''; document.getElementById('logMatchCount').textContent = ''; logFullContent = ''; } // 导出服务函数 window.SystemService = { fetchSystemMetrics, setRefreshInterval, stopLogAutoRefresh, refreshLogs, scrollToLogBottom, switchLogTab, initLogViewer, loadTrainingLogFiles, loadSelectedTrainingLog, loadLogFiles, loadSelectedLog, filterLogContent, clearLogContent };