diff --git a/internal/handler/metrics.go b/internal/handler/metrics.go
index 9056af2..fbd7482 100644
--- a/internal/handler/metrics.go
+++ b/internal/handler/metrics.go
@@ -326,6 +326,34 @@ var metricsTemplate = `
border: 1px solid #ddd;
margin-bottom: 15px;
}
+ .time-range-buttons {
+ margin: 15px 0;
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ }
+
+ .time-btn {
+ padding: 8px 16px;
+ border: 1px solid #ddd;
+ background: white;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.3s;
+ min-width: 80px;
+ text-align: center;
+ }
+
+ .time-btn:hover {
+ background: #f8f9fa;
+ }
+
+ .time-btn.active {
+ background: #007bff;
+ color: white;
+ border-color: #0056b3;
+ }
@@ -446,14 +474,30 @@ var metricsTemplate = `
历史数据
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -585,9 +629,14 @@ var metricsTemplate = `
// 每5秒自动刷新
setInterval(refreshMetrics, 5000);
- // ��加图表相关代码
- function loadHistoryData() {
- const hours = document.getElementById('timeRange').value;
+ // 修改图表加载相关代码
+ let currentCharts = {
+ requests: null,
+ errorRate: null,
+ bytes: null
+ };
+
+ function loadHistoryData(hours) {
fetch('/metrics/history?hours=' + hours, {
headers: {
'Authorization': 'Bearer ' + token
@@ -606,102 +655,67 @@ var metricsTemplate = `
}
});
- // 清除旧图表
- document.getElementById('historyChart').innerHTML = '';
-
- // 创建新图表
- document.getElementById('historyChart').innerHTML = '' +
- '
请求数
' +
- '
' +
- '' +
- '
' +
- '
错误率
' +
- '
' +
- '' +
- '
' +
- '
流量
' +
- '
' +
- '' +
- '
' +
- '
';
-
- // 绘制图表
- new Chart(document.getElementById('requestsChart'), {
- type: 'line',
- data: {
- labels: labels,
- datasets: [{
- label: '总请求数',
- data: data.map(m => m.total_requests),
- borderColor: '#4CAF50',
- fill: false
- }]
- },
- options: {
- scales: {
- x: {
- ticks: {
- maxRotation: 45,
- minRotation: 45
- }
- }
- }
- }
- });
-
- new Chart(document.getElementById('errorRateChart'), {
- type: 'line',
- data: {
- labels: labels,
- datasets: [{
- label: '错误率',
- data: data.map(m => (m.error_rate * 100).toFixed(2)),
- borderColor: '#dc3545',
- fill: false
- }]
- },
- options: {
- scales: {
- x: {
- ticks: {
- maxRotation: 45,
- minRotation: 45
- }
- }
- }
- }
- });
-
- new Chart(document.getElementById('bytesChart'), {
- type: 'line',
- data: {
- labels: labels,
- datasets: [{
- label: '传输字节',
- data: data.map(m => m.total_bytes / 1024 / 1024), // 转换为MB
- borderColor: '#17a2b8',
- fill: false
- }]
- },
- options: {
- scales: {
- x: {
- ticks: {
- maxRotation: 45,
- minRotation: 45
- }
- }
- }
- }
- });
+ // 更新或创建图表
+ updateChart('requestsChart', currentCharts.requests, labels, data, '请求数',
+ m => m.total_requests, '#007bff');
+ updateChart('errorRateChart', currentCharts.errorRate, labels, data, '错误率 (%)',
+ m => m.error_rate * 100, '#dc3545');
+ updateChart('bytesChart', currentCharts.bytes, labels, data, '流量 (MB)',
+ m => m.total_bytes / (1024 * 1024), '#28a745');
});
}
- // 监听时间范围变化
- document.getElementById('timeRange').addEventListener('change', loadHistoryData);
+ function updateChart(canvasId, chartInstance, labels, data, label, valueGetter, color) {
+ const ctx = document.getElementById(canvasId).getContext('2d');
+
+ if (chartInstance) {
+ chartInstance.data.labels = labels;
+ chartInstance.data.datasets[0].data = data.map(valueGetter);
+ chartInstance.update();
+ } else {
+ chartInstance = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: labels,
+ datasets: [{
+ label: label,
+ data: data.map(valueGetter),
+ borderColor: color,
+ tension: 0.1,
+ fill: false
+ }]
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ scales: {
+ x: {
+ ticks: {
+ maxRotation: 45,
+ minRotation: 45
+ }
+ }
+ }
+ }
+ });
+
+ if (canvasId === 'requestsChart') currentCharts.requests = chartInstance;
+ if (canvasId === 'errorRateChart') currentCharts.errorRate = chartInstance;
+ if (canvasId === 'bytesChart') currentCharts.bytes = chartInstance;
+ }
+ }
+
+ // 时间范围按钮处理
+ document.querySelectorAll('.time-btn').forEach(btn => {
+ btn.addEventListener('click', function() {
+ document.querySelectorAll('.time-btn').forEach(b => b.classList.remove('active'));
+ this.classList.add('active');
+ loadHistoryData(this.dataset.hours);
+ });
+ });
// 初始加载历史数据
- loadHistoryData();
+ loadHistoryData(24);
@@ -745,14 +759,30 @@ func (h *ProxyHandler) MetricsDashboardHandler(w http.ResponseWriter, r *http.Re
历史数据
-
-
+
+
+
+
+
+
+
+
+
+
+
+
`, 1)