From 260bddb56b71effb4ce7d1552a3c7630d09099b5 Mon Sep 17 00:00:00 2001 From: wood chen Date: Sun, 1 Dec 2024 01:49:50 +0800 Subject: [PATCH] refactor(public): improve metrics loading and display logic - Updated the metrics API endpoint from '/metrics' to '/api/metrics' for better organization. - Added data validation to ensure the metrics data received is an object, enhancing error handling. - Refactored the updateMetricsDisplay function to dynamically create metric items, improving the display of metrics. - Implemented HTML escaping for metric keys and values to prevent XSS vulnerabilities. - Cleared existing content in the metrics container before updating, ensuring a clean display. --- public/index.html | 102 ++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 63 deletions(-) diff --git a/public/index.html b/public/index.html index 624234a..bc9e69d 100644 --- a/public/index.html +++ b/public/index.html @@ -210,77 +210,53 @@ async function loadMetrics() { try { - const response = await fetch('/metrics'); - const metrics = await response.json(); - updateMetricsDisplay(metrics); + const response = await fetch('/api/metrics'); + const data = await response.json(); + + // 添加数据验证 + if (!data || typeof data !== 'object') { + throw new Error('Invalid metrics data received'); + } + + updateMetricsDisplay(data); } catch (error) { console.error('Error loading metrics:', error); + document.getElementById('metrics-container').innerHTML = + '

加载指标数据时出错,请稍后重试

'; } } - function updateMetricsDisplay(metrics) { - const metricsHtml = ` -
-
-

基础指标

-
-
运行时间:${formatDuration(metrics?.uptime || 0)}
-
启动时间:${new Date(metrics?.start_time || Date.now()).toLocaleString()}
-
-
- -
-

系统指标

-
-
CPU核心数:${metrics?.num_cpu || 0}
-
Goroutine数:${metrics?.num_goroutine || 0}
-
内存使用:${formatBytes(metrics?.memory_stats?.heap_alloc || 0)}
-
系统内存:${formatBytes(metrics?.memory_stats?.heap_sys || 0)}
-
平均延迟:${formatLatency(metrics?.average_latency || 0)}
-
-
- -
-

热门引用来源 (5分钟统计)

-
- ${metrics?.top_referers ? Object.entries(metrics.top_referers) - .sort(([, a], [, b]) => b - a) - .slice(0, 10) - .map(([referer, count]) => ` -
- ${referer} - ${count} -
- `).join('') : ''} -
-
-
- `; + function updateMetricsDisplay(metricsData) { + // 确保 metricsData 是有效对象 + if (!metricsData || typeof metricsData !== 'object') { + console.error('Invalid metrics data'); + return; + } + + const container = document.getElementById('metrics-container'); + container.innerHTML = ''; // 清空现有内容 + + // 使用 Object.entries 之前进行安全检查 + const entries = Object.entries(metricsData).filter(([key, value]) => key && value !== undefined); - const metricsElement = document.getElementById('system-metrics'); - if (metricsElement) { - metricsElement.innerHTML = metricsHtml; - } + entries.forEach(([key, value]) => { + const metricDiv = document.createElement('div'); + metricDiv.className = 'metric-item'; + metricDiv.innerHTML = ` +

${escapeHtml(key)}

+

${escapeHtml(String(value))}

+ `; + container.appendChild(metricDiv); + }); } - function formatBytes(bytes) { - const units = ['B', 'KB', 'MB', 'GB']; - let size = bytes; - let unitIndex = 0; - while (size >= 1024 && unitIndex < units.length - 1) { - size /= 1024; - unitIndex++; - } - return `${size.toFixed(2)} ${units[unitIndex]}`; - } - - function formatDuration(ns) { - const duration = ns / 1e9; // 转换为秒 - const days = Math.floor(duration / 86400); - const hours = Math.floor((duration % 86400) / 3600); - const minutes = Math.floor((duration % 3600) / 60); - const seconds = Math.floor(duration % 60); - return `${days}天 ${hours}时 ${minutes}分 ${seconds}秒`; + function escapeHtml(unsafe) { + return unsafe + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); } // 定期更新监控数据