Files
YG_FT_Platform/web/js/services/system.js
WIN-JHFT4D3SIVT\caoxiaozhu 513e96082c 重构了main.html的主函数
重构了大量的页面的sidebar
优化了代码结构
2026-02-02 09:22:52 +08:00

393 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 系统监控服务
* 处理系统性能指标获取和展示
*/
// 日志自动刷新相关变量
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 = '<option value="">加载中...</option>';
try {
const response = await fetch(`${window.API_BASE}/training-log-files`);
const result = await response.json();
if (result.code === 0 && result.data) {
logSelect.innerHTML = '<option value="">请选择训练日志</option>';
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 = '<option value="">暂无训练日志</option>';
document.getElementById('logContent').textContent = '暂无训练日志';
document.getElementById('logFileInfo').textContent = '无训练日志';
}
} catch (error) {
console.error('加载训练日志列表失败:', error);
logSelect.innerHTML = '<option value="">加载失败</option>';
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 = '<option value="">加载中...</option>';
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 = '<option value="">请选择日志文件</option>';
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 = '<option value="">暂无日志文件</option>';
document.getElementById('logContent').textContent = '该日期暂无日志文件';
document.getElementById('logFileInfo').textContent = '无日志文件';
}
} else {
logTypeSelect.innerHTML = '<option value="">暂无日志文件</option>';
document.getElementById('logContent').textContent = '该日期暂无日志文件';
document.getElementById('logFileInfo').textContent = '无日志文件';
}
} catch (error) {
console.error('加载日志文件列表失败:', error);
logTypeSelect.innerHTML = '<option value="">加载失败</option>';
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
};