210 lines
7.1 KiB
JavaScript
210 lines
7.1 KiB
JavaScript
layui.use(['element', 'layer'], function(){
|
|
var element = layui.element;
|
|
var layer = layui.layer;
|
|
var $ = layui.$;
|
|
|
|
// 初始化所有图表
|
|
var cpuChart = echarts.init(document.getElementById('cpu-chart'));
|
|
var memoryChart = echarts.init(document.getElementById('memory-chart'));
|
|
var diskChart = echarts.init(document.getElementById('disk-chart'));
|
|
var networkChart = echarts.init(document.getElementById('network-chart'));
|
|
|
|
// 更新系统状态
|
|
function updateSystemStatus() {
|
|
fetch('/api/monitor/status', {
|
|
credentials: 'include'
|
|
})
|
|
.then(response => {
|
|
if (response.status === 401) {
|
|
window.location.href = '/login';
|
|
throw new Error('认证失败');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
if (data.error) {
|
|
layer.msg(data.error);
|
|
return;
|
|
}
|
|
|
|
// 更新基础信息
|
|
$('#uptime').text(formatDuration(Math.floor(data.system.uptime / 1e9))); // 转换纳秒为秒
|
|
$('#active-users').text(data.system.active_users);
|
|
$('#total-devices').text(data.system.total_devices);
|
|
$('#load-avg').text(data.cpu.load_avg.map(v => v.toFixed(2)).join(' '));
|
|
|
|
// 更新系统信息
|
|
$('#hostname').text(data.host.hostname);
|
|
$('#os').text(data.host.os);
|
|
$('#platform').text(data.host.platform);
|
|
$('#kernel').text(data.host.kernel_version);
|
|
$('#cpu-model').text(data.cpu.model_name);
|
|
$('#cpu-cores').text(data.cpu.core_count);
|
|
$('#boot-time').text(new Date(data.host.boot_time).toLocaleString());
|
|
|
|
// 更新进程列表
|
|
var processHtml = '';
|
|
data.process.list.forEach(function(proc) {
|
|
processHtml += `
|
|
<tr>
|
|
<td>${proc.pid}</td>
|
|
<td>${proc.name}</td>
|
|
<td>${proc.cpu.toFixed(1)}%</td>
|
|
<td>${proc.memory.toFixed(1)}%</td>
|
|
<td>${formatDuration(Math.floor((Date.now() - proc.created) / 1000))}</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
$('#process-list').html(processHtml);
|
|
$('#total-processes').text(data.process.total);
|
|
|
|
// 更新图表
|
|
updateCPUChart(data.cpu);
|
|
updateMemoryChart(data.memory);
|
|
updateDiskChart(data.disk);
|
|
updateNetworkChart(data.network);
|
|
})
|
|
.catch(error => {
|
|
layer.msg('获取系统状态失败:' + error.message);
|
|
});
|
|
}
|
|
|
|
// 更新CPU图表
|
|
function updateCPUChart(cpu) {
|
|
var option = {
|
|
title: { text: 'CPU使用率' },
|
|
tooltip: { formatter: '{b}: {c}%' },
|
|
series: [{
|
|
type: 'gauge',
|
|
min: 0,
|
|
max: 100,
|
|
detail: { formatter: '{value}%' },
|
|
data: [{ value: cpu.usage.toFixed(1), name: 'CPU' }]
|
|
}]
|
|
};
|
|
cpuChart.setOption(option);
|
|
}
|
|
|
|
// 更新内存图表
|
|
function updateMemoryChart(memory) {
|
|
var used = (memory.used / 1024 / 1024 / 1024).toFixed(1);
|
|
var free = (memory.free / 1024 / 1024 / 1024).toFixed(1);
|
|
var option = {
|
|
title: { text: '内存使用情况' },
|
|
tooltip: { formatter: '{b}: {c}GB ({d}%)' },
|
|
series: [{
|
|
type: 'pie',
|
|
radius: ['50%', '70%'],
|
|
data: [
|
|
{ value: used, name: '已用内存' },
|
|
{ value: free, name: '空闲内存' }
|
|
]
|
|
}]
|
|
};
|
|
memoryChart.setOption(option);
|
|
}
|
|
|
|
// 更新磁盘图表
|
|
function updateDiskChart(disk) {
|
|
var option = {
|
|
title: { text: '磁盘使用情况' },
|
|
tooltip: {
|
|
formatter: function(params) {
|
|
var data = params.data;
|
|
return `${params.name}<br/>
|
|
总空间: ${formatSize(data.total)}<br/>
|
|
已用空间: ${formatSize(data.used)}<br/>
|
|
剩余空间: ${formatSize(data.free)}<br/>
|
|
使用率: ${data.usage_rate.toFixed(1)}%`;
|
|
}
|
|
},
|
|
series: [{
|
|
type: 'pie',
|
|
radius: '60%',
|
|
data: disk.partitions.map(p => ({
|
|
name: p.mountpoint,
|
|
value: p.usage_rate,
|
|
total: p.total,
|
|
used: p.used,
|
|
free: p.free,
|
|
usage_rate: p.usage_rate
|
|
}))
|
|
}]
|
|
};
|
|
diskChart.setOption(option);
|
|
}
|
|
|
|
// 更新网络图表
|
|
function updateNetworkChart(network) {
|
|
var option = {
|
|
title: { text: '网络流量' },
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
formatter: function(params) {
|
|
return params.map(p =>
|
|
`${p.seriesName}: ${formatSize(p.value)}/s`
|
|
).join('<br/>');
|
|
}
|
|
},
|
|
legend: { data: ['发送', '接收'] },
|
|
xAxis: {
|
|
type: 'category',
|
|
data: network.interfaces.map(i => i.name)
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLabel: {
|
|
formatter: function(value) {
|
|
return formatSize(value) + '/s';
|
|
}
|
|
}
|
|
},
|
|
series: [{
|
|
name: '发送',
|
|
type: 'bar',
|
|
data: network.interfaces.map(i => i.bytes_sent)
|
|
}, {
|
|
name: '接收',
|
|
type: 'bar',
|
|
data: network.interfaces.map(i => i.bytes_recv)
|
|
}]
|
|
};
|
|
networkChart.setOption(option);
|
|
}
|
|
|
|
// 格式化文件大小
|
|
function formatSize(bytes) {
|
|
if (bytes === 0) return '0 B';
|
|
var k = 1024;
|
|
var sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
|
|
}
|
|
|
|
// 格式化时间
|
|
function formatDuration(seconds) {
|
|
var days = Math.floor(seconds / 86400);
|
|
var hours = Math.floor((seconds % 86400) / 3600);
|
|
var minutes = Math.floor((seconds % 3600) / 60);
|
|
var parts = [];
|
|
if (days > 0) parts.push(days + '天');
|
|
if (hours > 0) parts.push(hours + '小时');
|
|
if (minutes > 0) parts.push(minutes + '分钟');
|
|
return parts.join(' ') || '0分钟';
|
|
}
|
|
|
|
// 初始加载
|
|
updateSystemStatus();
|
|
|
|
// 定时更新
|
|
setInterval(updateSystemStatus, 5000);
|
|
|
|
// 窗口大小改变时重绘图表
|
|
window.onresize = function(){
|
|
cpuChart.resize();
|
|
memoryChart.resize();
|
|
diskChart.resize();
|
|
networkChart.resize();
|
|
};
|
|
});
|