async function loadMetrics() { try { const token = localStorage.getItem('token'); if (!token) { window.location.href = '/metrics/ui'; return; } const response = await fetch('/metrics', { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { if (response.status === 401) { window.location.href = '/metrics/ui'; return; } throw new Error('加载监控数据失败'); } const metrics = await response.json(); displayMetrics(metrics); } catch (error) { showMessage(error.message, true); } } function displayMetrics(metrics) { const container = document.getElementById('metrics'); container.innerHTML = ''; // 添加基本信息 addSection(container, '基本信息', { '运行时间': metrics.uptime, '总请求数': metrics.totalRequests, '活跃请求数': metrics.activeRequests, '错误请求数': metrics.totalErrors, '总传输字节': formatBytes(metrics.totalBytes) }); // 添加状态码统计 addSection(container, '状态码统计', metrics.statusStats); // 添加路径统计 addSection(container, '路径统计', metrics.pathStats); // 添加来源统计 addSection(container, '来源统计', metrics.refererStats); // 添加延迟统计 addSection(container, '延迟统计', { '平均延迟': `${metrics.avgLatency}ms`, '延迟分布': metrics.latencyBuckets }); } function addSection(container, title, data) { const section = document.createElement('div'); section.className = 'metrics-section'; const titleElem = document.createElement('h2'); titleElem.textContent = title; section.appendChild(titleElem); const content = document.createElement('div'); content.className = 'metrics-content'; for (const [key, value] of Object.entries(data)) { const item = document.createElement('div'); item.className = 'metrics-item'; item.innerHTML = `${key}: ${value}`; content.appendChild(item); } section.appendChild(content); container.appendChild(section); } function formatBytes(bytes) { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } function showMessage(msg, isError = false) { const msgDiv = document.getElementById('message'); if (!msgDiv) return; msgDiv.textContent = msg; msgDiv.className = isError ? 'error' : 'success'; msgDiv.style.display = 'block'; setTimeout(() => { msgDiv.style.display = 'none'; }, 5000); } // 初始加载监控数据 loadMetrics(); // 每30秒刷新一次数据 setInterval(loadMetrics, 30000);