mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 16:41:54 +08:00
feat(metrics): enhance metrics dashboard with time range buttons and chart updates
- Replaced the time range dropdown with a set of buttons for selecting different time ranges (1 hour, 6 hours, 12 hours, 24 hours, 3 days, 5 days, 7 days, 15 days, 30 days). - Improved the styling of the time range buttons for better user experience. - Refactored chart loading logic to update existing charts instead of recreating them, enhancing performance and user experience. - Added functionality to dynamically load historical data based on the selected time range, improving data visualization capabilities.
This commit is contained in:
parent
91d4686713
commit
b69a78eae0
@ -326,6 +326,34 @@ var metricsTemplate = `
|
|||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
margin-bottom: 15px;
|
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;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -446,14 +474,30 @@ var metricsTemplate = `
|
|||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>历史数据</h2>
|
<h2>历史数据</h2>
|
||||||
<select id="timeRange">
|
<div class="time-range-buttons">
|
||||||
<option value="1">最近1小时</option>
|
<button class="time-btn" data-hours="1">1小时</button>
|
||||||
<option value="6">最近6小时</option>
|
<button class="time-btn" data-hours="6">6小时</button>
|
||||||
<option value="24">最近24小时</option>
|
<button class="time-btn" data-hours="12">12小时</button>
|
||||||
<option value="168">最近7天</option>
|
<button class="time-btn active" data-hours="24">24小时</button>
|
||||||
<option value="720">最近30天</option>
|
<button class="time-btn" data-hours="72">3天</button>
|
||||||
</select>
|
<button class="time-btn" data-hours="120">5天</button>
|
||||||
<div id="historyChart"></div>
|
<button class="time-btn" data-hours="168">7天</button>
|
||||||
|
<button class="time-btn" data-hours="360">15天</button>
|
||||||
|
<button class="time-btn" data-hours="720">30天</button>
|
||||||
|
</div>
|
||||||
|
<div id="historyChart">
|
||||||
|
<div class="chart-container">
|
||||||
|
<div class="chart">
|
||||||
|
<canvas id="requestsChart"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="chart">
|
||||||
|
<canvas id="errorRateChart"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="chart">
|
||||||
|
<canvas id="bytesChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span id="lastUpdate"></span>
|
<span id="lastUpdate"></span>
|
||||||
@ -585,9 +629,14 @@ var metricsTemplate = `
|
|||||||
// 每5秒自动刷新
|
// 每5秒自动刷新
|
||||||
setInterval(refreshMetrics, 5000);
|
setInterval(refreshMetrics, 5000);
|
||||||
|
|
||||||
// <20><>加图表相关代码
|
// 修改图表加载相关代码
|
||||||
function loadHistoryData() {
|
let currentCharts = {
|
||||||
const hours = document.getElementById('timeRange').value;
|
requests: null,
|
||||||
|
errorRate: null,
|
||||||
|
bytes: null
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadHistoryData(hours) {
|
||||||
fetch('/metrics/history?hours=' + hours, {
|
fetch('/metrics/history?hours=' + hours, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Bearer ' + token
|
'Authorization': 'Bearer ' + token
|
||||||
@ -606,102 +655,67 @@ var metricsTemplate = `
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 清除旧图表
|
// 更新或创建图表
|
||||||
document.getElementById('historyChart').innerHTML = '';
|
updateChart('requestsChart', currentCharts.requests, labels, data, '请求数',
|
||||||
|
m => m.total_requests, '#007bff');
|
||||||
// 创建新图表
|
updateChart('errorRateChart', currentCharts.errorRate, labels, data, '错误率 (%)',
|
||||||
document.getElementById('historyChart').innerHTML = '<div class="chart-container">' +
|
m => m.error_rate * 100, '#dc3545');
|
||||||
'<h3>请求数</h3>' +
|
updateChart('bytesChart', currentCharts.bytes, labels, data, '流量 (MB)',
|
||||||
'<div class="chart">' +
|
m => m.total_bytes / (1024 * 1024), '#28a745');
|
||||||
'<canvas id="requestsChart"></canvas>' +
|
|
||||||
'</div>' +
|
|
||||||
'<h3>错误率</h3>' +
|
|
||||||
'<div class="chart">' +
|
|
||||||
'<canvas id="errorRateChart"></canvas>' +
|
|
||||||
'</div>' +
|
|
||||||
'<h3>流量</h3>' +
|
|
||||||
'<div class="chart">' +
|
|
||||||
'<canvas id="bytesChart"></canvas>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
// 绘制图表
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听时间范围变化
|
function updateChart(canvasId, chartInstance, labels, data, label, valueGetter, color) {
|
||||||
document.getElementById('timeRange').addEventListener('change', loadHistoryData);
|
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);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- 添加 Chart.js -->
|
<!-- 添加 Chart.js -->
|
||||||
@ -745,14 +759,30 @@ func (h *ProxyHandler) MetricsDashboardHandler(w http.ResponseWriter, r *http.Re
|
|||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>历史数据</h2>
|
<h2>历史数据</h2>
|
||||||
<select id="timeRange">
|
<div class="time-range-buttons">
|
||||||
<option value="1">最近1小时</option>
|
<button class="time-btn" data-hours="1">1小时</button>
|
||||||
<option value="6">最近6小时</option>
|
<button class="time-btn" data-hours="6">6小时</button>
|
||||||
<option value="24">最近24小时</option>
|
<button class="time-btn" data-hours="12">12小时</button>
|
||||||
<option value="168">最近7天</option>
|
<button class="time-btn active" data-hours="24">24小时</button>
|
||||||
<option value="720">最近30天</option>
|
<button class="time-btn" data-hours="72">3天</button>
|
||||||
</select>
|
<button class="time-btn" data-hours="120">5天</button>
|
||||||
<div id="historyChart"></div>
|
<button class="time-btn" data-hours="168">7天</button>
|
||||||
|
<button class="time-btn" data-hours="360">15天</button>
|
||||||
|
<button class="time-btn" data-hours="720">30天</button>
|
||||||
|
</div>
|
||||||
|
<div id="historyChart">
|
||||||
|
<div class="chart-container">
|
||||||
|
<div class="chart">
|
||||||
|
<canvas id="requestsChart"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="chart">
|
||||||
|
<canvas id="errorRateChart"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="chart">
|
||||||
|
<canvas id="bytesChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span id="lastUpdate"></span>`, 1)
|
<span id="lastUpdate"></span>`, 1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user