环境:网络管理 主机资源监控系统项目搭建 (保姆级教程 建议点赞 收藏)_搭建网络版信息管理系统-CSDN博客
效果图
下面3个文件的项目目录(python3.8.8的虚拟环境)
D:\py_siqintu\myproject5\Scripts\mytest.py
D:\py_siqintu\myproject5\Scripts\templates\main.html
D:\py_siqintu\myproject5\Scripts\static\css\style.css
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>System Information</title>
<script src="{{ url_for('static', filename='js/Bubble.js') }}"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script type="text/javascript" src="https://registry.npmmirror.com/jquery/3.7.1/files/dist/jquery.min.js"></script>
<script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.5.1/files/dist/echarts.min.js"></script>
</head>
<body>
<div class="head clearfix">
<h1 style="text-align: center;">主机资源监控系统</h1>
</div>
<div class="mainbox">
<ul class="clearfix nav1">
<li style="width: 22%">
<div class="box" style="padding-right: 0;">
<div class="tit">CPU负载Top5</div>
<div id="cpu-monitor" style="width: 340px;height:230px;"></div>
</div>
<div class="box">
<div class="tit">内存占用Top5</div>
<div id="memory-monitor" style="width: 340px;height:230px;" ></div>
</div>
</li>
<li style="width: 56%">
<div class="box">
<div class="boxnav mapc" style="height: 550px; position: relative">
<div class="mapnav1" style="display: flex;">
<img style="height: 200px; width: 250px; margin-top: 20px;" src="{{ url_for('static', filename='images/pc.png') }}" alt="PC Image">
<div style="margin-top: 20px;">
<div style="font-family: Arial, sans-serif; font-size: 14px; border: 1px solid #ccc; border-radius: 5px; padding: 10px; background-color: #f9f9f9; width: 700px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 5px; border-bottom: 1px solid #ddd; padding-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">系统名字:</p>
<p id="SystemNamessr2" style="margin: 0;"></p>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">系统描述:</p>
<p id="SystemDescription" style="margin: 0;"></p>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">内存大小:</p>
<p id="Memorysize" style="margin: 0;"></p>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">运行时间:</p>
<p id="Systemuptime" style="margin: 0;"></p>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">TCP活跃连接数:</p>
<p id="tcp_connections" style="margin: 0;"></p>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">当前进程总数:</p>
<p id="process_count" style="margin: 0;"></p>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<p style="font-weight: bold; margin: 0;">本机IP:</p>
<p id="ip_address" style="margin: 0;"></p>
</div>
</div>
<script>var myurCON = "http://" + window.location.host+"/config/";
setInterval(()=>{
fetch(myurCON).then(res=>{
return res.json()
}).then((json)=>{
console.log(json);
var SystemNamessr2 = document.getElementById('SystemNamessr2');
SystemNamessr2.innerHTML = json.ssyname;
var SystemDescription = document.getElementById('SystemDescription');
SystemDescription.innerHTML = json.sysDecr;
var Memorysize = document.getElementById('Memorysize');
let memoryInKiB = json.mem;
let memoryReadable = (memoryInKiB / 1048576).toFixed(2) + " GB"
Memorysize.innerHTML = memoryReadable;
var Systemuptime = document.getElementById('Systemuptime');
let uptimeInHundredths = json.sysUptime;
let uptimeInSeconds = uptimeInHundredths * 0.01;
let days = Math.floor(uptimeInSeconds / (24 * 3600));
let hours = Math.floor((uptimeInSeconds % (24 * 3600)) / 3600);
let minutes = Math.floor((uptimeInSeconds % 3600) / 60);
let seconds = Math.floor(uptimeInSeconds % 60);
let uptimeReadable = `${days}天 ${hours}小时 ${minutes}分钟 ${seconds}秒`;
Systemuptime.innerHTML = uptimeReadable;
})
},1000)</script>
</div>
</div>
<div style="display: flex;">
<div id="gaugeChart" class="chart" style="width: 350px;height:300px;"></div>
<script>
var gaugeDom = document.getElementById('gaugeChart');
var gaugeChart = echarts.init(gaugeDom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app={}
var gaugeOption = {
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
series: [
{
name: 'Pressure',
type: 'gauge',
detail: {
formatter: '{value}'
},
data: [
{
value: 98,
name: 'CPU负载'
}
]
}
]
};
if (gaugeOption && typeof gaugeOption === 'object') {
gaugeChart.setOption(gaugeOption);
}
var myurl3 = "http://" + window.location.host+"/cpu/";
setInterval(()=>{
fetch(myurl3).then(res=>{
return res.json()
}).then((json)=>{
gaugeOption.series[0].data[0].value = json.cpu;
gaugeChart.setOption(gaugeOption);
})
},1000)
</script>
<div id="disk_usage" style="width: 350px;height:300px;"></div>
<script>
var domdisk_usage = document.getElementById('disk_usage');
var myChartdisk_usage = echarts.init(domdisk_usage, null, {
renderer: 'canvas',
useDirtyRect: false
});
var mydisk_usage = "http://" + window.location.host + "/get_disk/";
var optiondisk_usage = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c}% ({d}%)'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: 'Disk Usage',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '60%'],
startAngle: 180,
endAngle: 360,
data: [
{ name: 'Free', value: 0 },
{ name: 'Used', value: 0 }
]
}
]
};
myChartdisk_usage.setOption(optiondisk_usage);
setInterval(() => {
fetch(mydisk_usage)
.then(response => response.json())
.then(data => {
console.log(data);
const free = data.free;
const used = data.used;
const total = data.total;
if (typeof free === 'number' && typeof used === 'number' && typeof total === 'number') {
const freePercent = (free / total) * 100;
const usedPercent = (used / total) * 100;
myChartdisk_usage.setOption({
series: [
{
data: [
{ name: 'Free', value: freePercent },
{ name: 'Used', value: usedPercent }
]
}
]
});
} else {
console.error('Invalid data format', data);
}
})
.catch(error => {
console.error('Error fetching disk usage:', error);
});
}, 1000);
</script>
<div id="memory_usage" class="chart" style="height: 300px; width: 350px;"></div>
</div>
<script>
var memory_usageDom = document.getElementById('memory_usage');
var memory_usageChart = echarts.init(memory_usageDom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app={}
var memory_usageOption = {
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
series: [
{
name: 'Pressure',
type: 'gauge',
detail: {
formatter: '{value}'
},
data: [
{
value: 98,
name: '内存占有率'
}
]
}
]
};
if (memory_usageOption && typeof memory_usageOption === 'object') {
memory_usageChart.setOption(memory_usageOption);
}
var myurl99 = "http://" + window.location.host+"/Memoryusage/";
setInterval(()=>{
fetch(myurl99).then(res=>{
return res.json()
}).then((json)=>{
memory_usageOption.series[0].data[0].value = json.memory_usage;
memory_usageChart.setOption(memory_usageOption);
})},1000);
</script>
</li>
<li style="width: 22%">
<div class="box">
<div class="tit">网络接口状态统计</div>
<div id="echart3">
<div id="interface_status" style="height: 230px; width: 350px;"></div>
<script>
var interfaceDataUrl = "http://" + window.location.host + "/interface_status/";
let interfaceChart = echarts.init(document.getElementById('interface_status'));
let interfaceChartOption = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
type: 'category',
data: [],
axisLabel: {
interval: 0,
rotate: 45
}
},
yAxis: {
type: 'value',
name: '',
minInterval: 1
},
series: [
{
name: '',
type: 'bar',
data: [],
itemStyle: {
color: function (params) {
let colorMap = {
'运行中': '#4caf50',
'已关闭': '#f44336',
'未启用': '#9e9e9e'
};
return colorMap[params.name] || '#000';
}
}
}
]
};
interfaceChart.setOption(interfaceChartOption);
setInterval(() => {
fetch(interfaceDataUrl)
.then(response => response.json())
.then(data => {
let statusNames = {
up: '运行中',
down: '已关闭',
notPresent: '未启用'
};
let statusCount = {
'运行中': 0,
'已关闭': 0,
'未启用': 0
};
data.interfaces.forEach(interface => {
let status = statusNames[interface.status];
if (statusCount[status] !== undefined) {
statusCount[status]++;
}
});
interfaceChartOption.xAxis.data = Object.keys(statusCount);
interfaceChartOption.series[0].data = Object.values(statusCount);
interfaceChart.setOption(interfaceChartOption);
})
.catch(error => {
console.error("Error fetching interface data:", error);
});
}, 1000);
</script>
</div>
</div>
<div class="box">
<div class="tit">丢包率和误包率</div>
<div id="error_loss_chart" style="width: 350px;height:200px; margin-top: 20px;"></div>
</div>
</li>
</ul>
<div class="box" style="padding: 20px 0; height: 335px;">
<ul class="clearfix nav2 ">
<li style="width:25%;"><div class="tit01">实时流量(MB)</div>
<div id="net_s" style="width: 350px;height:240px; margin-top: 20px;"></div>
<script>
var net_s_Dom = document.getElementById('net_s');
var myChart_net_s = echarts.init(net_s_Dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var x_a = new Array();
for(var i =0;i<=200;i++)
{
x_a.push(i)
}
var app={}
var option_net_s = {
animation: false,
title: {
text: ''
},
tooltip: {
trigger: 'axis',
axisPointer: {
type:'',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['入流量', '出流量']
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: x_a
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '入流量',
type: 'line',
emphasis: {
focus: 'series'
},
data: []
},
{
name: '出流量',
type: 'line',
emphasis: {
focus: 'series'
},
data: [],
valueAnimation: false
}
]
};
myChart_net_s.setOption(option_net_s);
var mydata_net_in= new Array();
var mydata_net_out = new Array();
var net_last_in = 0;
var net_last_out = 0;
var myurl4 = "http://" + window.location.host+"/net_m/";
setInterval(()=>{
fetch(myurl4).then(res=>{
return res.json()
}).then((json)=>{
i = (json.in_s - net_last_in);
o = (json.out_s - net_last_out);
console.log(i,o);
if(i < 0)
i = i + 2**32;
if(o < 0)
o = o + 2**32
i = i / (1048576)
o = o / (1048576)
mydata_net_in.push(i);
mydata_net_out.push(o);
net_last_in = json.in_s
net_last_out = json.out_s
if (mydata_net_in.length > 200)
{
mydata_net_in.shift(json.in_s);
mydata_net_out.shift(json.out_s);
}
option_net_s.series[0].data=mydata_net_in;
option_net_s.series[1].data=mydata_net_out;
myChart_net_s.setOption(option_net_s);
})},1000);
</script>
</li>
<li style="width:25%"><div class="tit01">历史网络流量(5min)</div>
<div id="net_traffic_chart" style="width: 350px;height:350px;"></div>
<script>
var netTrafficContainer = document.getElementById('net_traffic_chart');
var netTrafficChart = echarts.init(netTrafficContainer, null, {
renderer: 'canvas',
useDirtyRect: false
});
var netTrafficOption = {
tooltip: { trigger: 'axis' },
legend: { data: ['入流量', '出流量'] },
xAxis: { type: 'category', boundaryGap: true, data: [] },
yAxis: { type: 'value', name: 'Traffic (MB)' },
series: [
{ name: 'Incoming Traffic', type: 'line', data: [] },
{ name: 'Outgoing Traffic', type: 'line', data: [] }
],
animationDuration: 0,
animationDurationUpdate: 3000,
animationEasing: 'linear',
animationEasingUpdate: 'linear'
};
netTrafficChart.setOption(netTrafficOption);
var trafficDataUrl = "http://" + window.location.host + "/net_h/";
setInterval(() => {
fetch(trafficDataUrl)
.then(response => response.json())
.then(data => {
var newTimeStamps = data.timestamps || [];
var newIncomingTraffic = data.net_in || [];
var newOutgoingTraffic = data.net_out || [];
netTrafficOption.xAxis.data = newTimeStamps.slice(-30);
netTrafficOption.series[0].data = newIncomingTraffic.slice(-30);
netTrafficOption.series[1].data = newOutgoingTraffic.slice(-30);
netTrafficChart.setOption(netTrafficOption);
})
.catch(error => console.error('Error fetching traffic data:', error));
}, 3000);
window.addEventListener('resize', netTrafficChart.resize);
</script>
<div class="ftechart" id="echart4"></div>
</li>
<li style="width:25%">
<div class="tit01">网络波动</div>
<div id="network_volatility" style="width: 300px; height: 300px;"></div>
<script>
var networkVolatilityDom = document.getElementById('network_volatility');
var networkVolatilityChart = echarts.init(networkVolatilityDom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var networkVolatilityOption = {
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} bytes'
}
},
series: [
{
name: '波动字节',
type: 'line',
smooth: true,
data: []
}
]
};
if (networkVolatilityOption && typeof networkVolatilityOption === 'object') {
networkVolatilityChart.setOption(networkVolatilityOption);
}
var myurlNetworkVolatility = "http://" + window.location.host + "/volatility/";
setInterval(() => {
fetch(myurlNetworkVolatility)
.then(res => res.json())
.then((json) => {
const currentTimestamp = new Date().toISOString();
if (json.volatility !== undefined) {
networkVolatilityOption.xAxis.data.push(currentTimestamp);
networkVolatilityOption.series[0].data.push(json.volatility);
}
if (networkVolatilityOption.xAxis.data.length > 10) {
networkVolatilityOption.xAxis.data.shift();
networkVolatilityOption.series[0].data.shift();
}
networkVolatilityChart.setOption(networkVolatilityOption);
})
.catch((error) => console.error("获取网络波动字节数据失败", error));
}, 1000);
</script>
</li>
<li style="width:25%"><div class="tit01">TCP&UDP</div>
<div id="tcp_udp_chart" style="width: 350px;height:240px; margin-top: 20px;"></div>
<script>
var tcp_udp_Dom = document.getElementById('tcp_udp_chart');
var tcp_udp_chart = echarts.init(tcp_udp_Dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var tcp_udp_option = {
title: {
text: ''
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['TCP In', 'TCP Out', 'UDP In', 'UDP Out']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
yAxis: [
{
type: 'value',
name: 'TCP Packets',
min: 0,
max: 800000,
position: 'left',
axisLine: {
lineStyle: {
color: '#5470C6'
}
}
},
{
type: 'value',
name: 'UDP Packets',
min: 0,
max: 800000,
position: 'right',
axisLine: {
lineStyle: {
color: '#91CC75'
}
}
}
],
series: [
{
name: 'TCP In',
type: 'line',
yAxisIndex: 0,
data: []
},
{
name: 'TCP Out',
type: 'line',
yAxisIndex: 0,
data: []
},
{
name: 'UDP In',
type: 'line',
yAxisIndex: 1,
data: []
},
{
name: 'UDP Out',
type: 'line',
yAxisIndex: 1,
data: []
}
]
};
tcp_udp_chart.setOption(tcp_udp_option);
var myurl2 = "http://" + window.location.host + "/tcp_udp_status/";
setInterval(() => {
fetch(myurl2)
.then(res => res.json())
.then(json => {
var now = new Date().toLocaleTimeString();
tcp_udp_option.xAxis.data.push(now);
if (tcp_udp_option.xAxis.data.length > 50) {
tcp_udp_option.xAxis.data.shift();
}
tcp_udp_option.series[0].data.push(json.tcp_in);
tcp_udp_option.series[1].data.push(json.tcp_out);
tcp_udp_option.series[2].data.push(json.udp_in);
tcp_udp_option.series[3].data.push(json.udp_out);
if (tcp_udp_option.series[0].data.length > 50) {
tcp_udp_option.series[0].data.shift();
tcp_udp_option.series[1].data.shift();
tcp_udp_option.series[2].data.shift();
tcp_udp_option.series[3].data.shift();
}
tcp_udp_chart.setOption(tcp_udp_option);
})
.catch(error => console.error('Error fetching TCP/UDP data:', error));
}, 1000);
</script>
<div class="" id="">
<div style="float: left; width: 50%; height: 200px" id="fb03"></div>
<div style="float: left; width: 50%; height: 200px" id="fb04"></div>
</div>
</li>
</ul>
</div>
</div>
<script>
var myur50 = "http://" + window.location.host+"/ip_addresses/";
setInterval(()=>{
fetch(myur50).then(res=>{
return res.json()
}).then((json)=>{
console.log(json)
var SystemDescription = document.getElementById('ip_address');
SystemDescription.innerHTML = json.ip_addresses.ip_addresses;
})
},1000)
var errorLossChartDom = document.getElementById('error_loss_chart');
var errorLossChart = echarts.init(errorLossChartDom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var errorLossChartOptions = {
title: {
text: ''
},
tooltip: {
trigger: 'axis'
},
legend: {
data: [
'In Packet Loss Rate',
'Out Packet Loss Rate',
'In Error Rate',
'Out Error Rate'
]
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
yAxis: {
type: 'value',
name: 'Rate (%)',
min: 0,
max: 100,
position: 'left',
axisLine: {
lineStyle: {
color: '#5470C6'
}
}
},
series: [
{
name: 'In Packet Loss Rate',
type: 'line',
data: [],
lineStyle: {
color: '#EE6666'
}
},
{
name: 'Out Packet Loss Rate',
type: 'line',
data: [],
lineStyle: {
color: '#5470C6'
}
},
{
name: 'In Error Rate',
type: 'line',
data: [],
lineStyle: {
color: '#91CC75'
}
},
{
name: 'Out Error Rate',
type: 'line',
data: [],
lineStyle: {
color: '#FAC858'
}
}
]
};
errorLossChart.setOption(errorLossChartOptions);
var errorLossDataUrl = "http://" + window.location.host + "/packet_loss_rate/";
setInterval(() => {
fetch(errorLossDataUrl)
.then(res => res.json())
.then(json => {
var now = new Date().toLocaleTimeString();
errorLossChartOptions.xAxis.data.push(now);
if (errorLossChartOptions.xAxis.data.length > 50) {
errorLossChartOptions.xAxis.data.shift();
}
errorLossChartOptions.series[0].data.push(json.in_packet_loss_rate);
errorLossChartOptions.series[1].data.push(json.out_packet_loss_rate);
errorLossChartOptions.series[2].data.push(json.in_error_rate);
errorLossChartOptions.series[3].data.push(json.out_error_rate);
if (errorLossChartOptions.series[0].data.length > 50) {
errorLossChartOptions.series[0].data.shift();
errorLossChartOptions.series[1].data.shift();
errorLossChartOptions.series[2].data.shift();
errorLossChartOptions.series[3].data.shift();
}
errorLossChart.setOption(errorLossChartOptions);
})
.catch(error => console.error('Error fetching Packet Loss & Error Rate data:', error));
}, 1000);
var cpuMonitorContainer = document.getElementById('cpu-monitor');
var cpuChart = echarts.init(cpuMonitorContainer, null, {
renderer: 'canvas',
useDirtyRect: false
});
var cpuChartOption = {
grid: {
left: '20%',
right: '10%',
top: '10%',
bottom: '10%'
},
xAxis: {
type: 'value',
max: 'dataMax',
name: 'CPU %',
nameLocation: 'middle',
nameGap: 30
},
yAxis: {
type: 'category',
data: [],
inverse: true,
name: '',
nameLocation: 'middle',
nameGap: 50,
nameTextStyle: {
fontSize: 16,
fontWeight: 'bold',
color: '#333'
}
},
series: [
{
name: 'CPU Usage',
type: 'bar',
data: [],
label: {
show: true,
position: 'right',
formatter: '{c}%',
valueAnimation: true
}
}
],
tooltip: {
trigger: 'item',
formatter: '{b}: {c}%'
},
legend: {
show: true,
data: ['CPU Usage']
},
animationDuration: 0,
animationDurationUpdate: 3000,
animationEasing: 'linear',
animationEasingUpdate: 'linear'
};
const processNames = [];
const processCpuUsage = [];
cpuChart.setOption(cpuChartOption);
window.addEventListener('resize', cpuChart.resize);
errorLossChart.setOption(errorLossChartOptions);
var cpuDataUrl = "http://" + window.location.host + "/top_processes/";
setInterval(() => {
fetch(cpuDataUrl)
.then(res => res.json())
.then(data => {
var processNames = [];
var processCpuUsage = [];
data.top_cpu_processes.forEach(process => {
processNames.push(process.name || `PID ${process.pid}`);
processCpuUsage.push(process.cpu_percent);
});
cpuChartOption.yAxis.data = processNames;
cpuChartOption.series[0].data = processCpuUsage;
cpuChart.setOption(cpuChartOption);
})
.catch(error => console.error('Error fetching CPU data:', error));
}, 1000);
var memoryMonitorContainer = document.getElementById('memory-monitor');
var memoryChart = echarts.init(memoryMonitorContainer, null, {
renderer: 'canvas',
useDirtyRect: false
});
var memoryChartOption = {
grid: {
left: '20%',
right: '10%',
top: '10%',
bottom: '10%'
},
xAxis: {
type: 'value',
max: 'dataMax',
name: 'Memory %',
nameLocation: 'middle',
nameGap: 30
},
yAxis: {
type: 'category',
data: [],
inverse: true,
name: '',
nameLocation: 'middle',
nameGap: 50,
nameTextStyle: {
fontSize: 16,
fontWeight: 'bold',
color: '#333'
}
},
series: [
{
name: 'Memory Usage',
type: 'bar',
data: [],
label: {
show: true,
position: 'right',
formatter: '{c}%',
valueAnimation: true
}
}
],
tooltip: {
trigger: 'item',
formatter: '{b}: {c}%'
},
legend: {
show: true,
data: ['Memory Usage']
},
animationDuration: 0,
animationDurationUpdate: 3000,
animationEasing: 'linear',
animationEasingUpdate: 'linear'
};
const processNames2 = [];
const processMemoryUsage = [];
memoryChart.setOption(memoryChartOption);
window.addEventListener('resize', memoryChart.resize);
var memoryDataUrl = "http://" + window.location.host + "/top_processes/";
setInterval(() => {
fetch(memoryDataUrl)
.then(res => res.json())
.then(data => {
var processNames2 = [];
var processMemoryUsage = [];
data.top_memory_processes.forEach(process => {
processNames2.push(process.name || `PID ${process.pid}`);
processMemoryUsage.push((process.memory_percent).toFixed(2));
});
memoryChartOption.yAxis.data = processNames2;
memoryChartOption.series[0].data = processMemoryUsage;
memoryChart.setOption(memoryChartOption);
})
.catch(error => console.error('Error fetching memory data:', error));
}, 1000);
var myur15 = "http://" + window.location.host+"/tcp_connections/";
setInterval(()=>{
fetch(myur15).then(res=>{
return res.json()
}).then((json)=>{
var tcp_connections2 = document.getElementById('tcp_connections');
tcp_connections2.innerHTML = json.tcp_active_connections;
})
},1000)
var myur16 = "http://" + window.location.host+"/process_count/";
setInterval(()=>{
fetch(myur16).then(res=>{
return res.json()
}).then((json)=>{
var process_count = document.getElementById('process_count');
process_count.innerHTML = json.process_count;
})
},1000)
</script>
</body>
</html>
mytest.py
import random
from pysnmp.hlapi import *
from flask import Flask,render_template
app = Flask(__name__)
myhost='localhost'
myport=161
mycommunity ='public'
myifindex ='.10'
myOIDs={
'os_version': '1.3.6.1.2.1.1.1.0',
'hostname': '1.3.6.1.2.1.1.5.0',
'cpu_count': '1.3.6.1.4.1.2021.11.50.0',
'disk_total': '1.3.6.1.4.1.2021.9.1.6.1',
'disk_used': '1.3.6.1.4.1.2021.9.1.8.1',
'disk_free': '1.3.6.1.4.1.2021.9.1.7.1',
'process_count': '1.3.6.1.2.1.25.1.6.0',
'tcp_active_connections': '1.3.6.1.2.1.6.9.0',
'interface_status': '1.3.6.1.2.1.2.2.1.8',
'sysDecr' : ".1.3.6.1.2.1.1.1.0",
'sysUptime' : ".1.3.6.1.2.1.1.3.0",
'sysName':".1.3.6.1.2.1.1.5.0",
'wlan_if_in':'1.3.6.1.2.1.2.2.1.10',
'wlan_if_out':'1.3.6.1.2.1.2.2.1.16',
'if_in' : ".1.3.6.1.2.1.2.2.1.10",
'if_out' : ".1.3.6.1.2.1.2.2.1.16",
'if_inpkt' : ".1.3.6.1.2.1.2.2.1.11",
'if_outpkt' : ".1.3.6.1.2.1.2.2.1.17",
'if_inbpkt' : ".1.3.6.1.2.1.2.2.1.12",
'if_outbpkt': ".1.3.6.1.2.1.2.2.1.18",
'if_speed' : ".1.3.6.1.2.1.2.2.1.5",
'mem_total' : ".1.3.6.1.2.1.25.2.2.0",
'cpu_loads' : ". 1.3.6.1.2.1.25.3.3.1.2",
'hrStorageSize':'1.3.6.1.2.1.25.2.3.1.5.4',
'hrStorageUsed':"1.3.6.1.2.1.25.2.3.1.6.4" ,
'if_in_discards': "1.3.6.1.2.1.2.2.1.13",
'if_out_discards': "1.3.6.1.2.1.2.2.1.19" ,
'if_in_errors': "1.3.6.1.2.1.2.2.1.14",
'if_out_errors': "1.3.6.1.2.1.2.2.1.20",
'ipAddrTable_oid' :'1.3.6.1.2.1.4.20.1.1',
}
def getTableRows(oids):
iterator = nextCmd(
SnmpEngine(),
CommunityData(mycommunity, mpModel=0),
UdpTransportTarget((myhost, myport)),
ContextData(),
*oids,
lexicographicMode = False)
ret = []
for errorIndication, errorStatus, errorIndex, varBinds in iterator:
count = ()
if errorIndication:
print(errorIndication)
break
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
break
else:
for varBind in varBinds:
count = count + (varBind[1]._value,)
ret.append(count)
return ret
def getObjs(oids):
iterator = getCmd(
SnmpEngine(),
CommunityData(mycommunity, mpModel=0),
UdpTransportTarget((myhost, myport)),
ContextData(),
*oids)
ret = []
errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
if errorIndication:
print(errorIndication)
return 0
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex)-1][0] or '?'))
return 0
else:
for varBind in varBinds:
ret.append(varBind[1]._value)
return ret
def get_memory_usage():
total_memory = getObjs([ObjectType(ObjectIdentity(myOIDs['hrStorageSize']))])
used_memory = getObjs([ObjectType(ObjectIdentity(myOIDs['hrStorageUsed']))])
if total_memory and used_memory and total_memory[0] > 0:
memory_usage = (used_memory[0] / total_memory[0]) * 100
return round(memory_usage, 2)
else:
return None
@app.route('/')
def index():
return render_template('main.html')
@app.route('/cpu/')
def cpu_used():
cpuoid=ObjectType(ObjectIdentity(myOIDs['cpu_loads']))
ret = getTableRows((cpuoid,))
cpuload=0
for i in ret:
cpuload += i[0]
print(cpuload)
return {'cpu':cpuload}
@app.route('/net_m/')
def net_used():
getoids=(ObjectType(ObjectIdentity(myOIDs['if_in']+'.41')),
ObjectType(ObjectIdentity(myOIDs['if_out']+'.41')))
in_out = getObjs(getoids)
return {'in_s':in_out[0],'out_s':in_out[1]}
@app.route('/config/')
def m_config():
getoids=(ObjectType(ObjectIdentity(myOIDs['sysDecr'])),
ObjectType(ObjectIdentity(myOIDs['sysUptime'])),
ObjectType(ObjectIdentity(myOIDs['mem_total'])),
ObjectType(ObjectIdentity(myOIDs['sysName'])),
)
configs = getObjs(getoids)
return {'sysDecr':configs[0].decode(),
'sysUptime':configs[1],
'mem':configs[2],
'ssyname': configs[3].decode(),
}
@app.route('/Memoryusage/')
def Memoryusage():
memory_usage = get_memory_usage()
return {
'memory_usage': memory_usage
}
@app.route('/tcp_udp_status/')
def tcp_udp_status():
tcp_in_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.6.10.0'))
tcp_out_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.6.11.0'))
udp_in_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.7.1.0'))
udp_out_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.7.4.0'))
tcp_udp_data = getObjs([tcp_in_oid,tcp_out_oid, udp_in_oid, udp_out_oid])
if tcp_udp_data:
return {
'tcp_in': tcp_udp_data[0],
'tcp_out': tcp_udp_data[1],
'udp_in': tcp_udp_data[2],
'udp_out': tcp_udp_data[3]
}
else:
return {'error': 'Failed to retrieve TCP/UDP statistics'}, 500
def get_packet_loss_rate():
getoids = (
ObjectType(ObjectIdentity(myOIDs['if_in_discards'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_out_discards'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_inpkt'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_outpkt'] + '.41'))
)
results = getObjs(getoids)
in_discards = results[0]
out_discards = results[1]
in_pkts = results[2]
out_pkts = results[3]
in_packet_loss_rate = (in_discards / in_pkts) * 100 if in_pkts > 0 else 0
out_packet_loss_rate = (out_discards / out_pkts) * 100 if out_pkts > 0 else 0
return round(in_packet_loss_rate, 2), round(out_packet_loss_rate, 2)
def get_error_rate():
getoids = (
ObjectType(ObjectIdentity(myOIDs['if_in_errors'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_out_errors'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_inpkt'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_outpkt'] + '.41'))
)
results = getObjs(getoids)
in_errors = results[0]
out_errors = results[1]
in_pkts = results[2]
out_pkts = results[3]
in_error_rate = (in_errors / in_pkts) * 100 if in_pkts > 0 else 0
out_error_rate = (out_errors / out_pkts) * 100 if out_pkts > 0 else 0
return round(in_error_rate, 2), round(out_error_rate, 2)
@app.route('/packet_loss_rate/')
def packet_loss_rate():
in_loss_rate, out_loss_rate = get_packet_loss_rate()
in_error_rate, out_error_rate = get_error_rate()
if None not in (in_loss_rate, out_loss_rate, in_error_rate, out_error_rate):
return {
'in_packet_loss_rate': in_loss_rate,
'out_packet_loss_rate': out_loss_rate,
'in_error_rate': in_error_rate,
'out_error_rate': out_error_rate
}
else:
return {'error': 'Failed to retrieve packet loss or error rate'}, 500
import ipaddress
import struct
def parse_ip_from_binary(binary_data):
try:
ip_address = ipaddress.ip_address(binary_data)
return str(ip_address)
except ValueError:
print(f"Invalid binary data: {binary_data}")
return None
def get_ip_addresses():
ip_addresses = []
ip_entries = getTableRows([ObjectType(ObjectIdentity(myOIDs['ipAddrTable_oid']))])
if ip_entries:
for entry in ip_entries:
ip_address = entry[0]
if isinstance(ip_address, bytes):
ip_address = parse_ip_from_binary(ip_address)
if ip_address:
ip_addresses.append(ip_address)
else:
print(f"Unexpected format: {ip_address}")
if ip_addresses:
return {"ip_addresses": ip_addresses}
else:
return {"error": "No valid IP addresses found"}
else:
return {"error": "Failed to retrieve IP addresses"}
import psutil
@app.route('/top_processes/')
def top_processes():
processes = []
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
try:
proc_info = proc.info
processes.append(proc_info)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
top_cpu_processes = sorted(processes, key=lambda x: x['cpu_percent'], reverse=True)[1:6]
top_memory_processes = sorted(processes, key=lambda x: x['memory_percent'], reverse=True)[:5]
return {
'top_cpu_processes': top_cpu_processes,
'top_memory_processes': top_memory_processes
}
@app.route('/interface_status/')
def interface_status():
interfaces = getTableRows([ObjectType(ObjectIdentity(myOIDs['interface_status']))])
status_map = {1: 'up', 2: 'down', 3: 'testing', 4: 'unknown', 5: 'dormant', 6: 'notPresent', 7: 'lowerLayerDown'}
interface_status = [{'interface_index': idx+1, 'status': status_map.get(status, 'unknown')} for idx, (status,) in enumerate(interfaces)]
return {'interfaces': interface_status}
@app.route('/tcp_connections/')
def tcp_connections():
tcp_active_connections = getObjs([ObjectType(ObjectIdentity(myOIDs['tcp_active_connections']))])
if tcp_active_connections:
return {'tcp_active_connections': tcp_active_connections[0]}
else:
return {'error': 'Failed to retrieve TCP connections'}, 500
@app.route('/process_count/')
def process_count():
process_count = getObjs([ObjectType(ObjectIdentity(myOIDs['process_count']))])
if process_count:
return {'process_count': process_count[0]}
else:
return {'error': 'Failed to retrieve process count'}, 500
# ip
@app.route('/ip_addresses/')
def ip_addresses():
ip_list = get_ip_addresses()
if ip_list:
return {'ip_addresses': ip_list}
else:
return {'error': 'Failed to retrieve IP addresses'}, 500
from collections import deque
import threading
import time
from datetime import datetime, timedelta
net_history_data = deque(maxlen=30)
def update_net_history():
while True:
getoids = (
ObjectType(ObjectIdentity(myOIDs['if_in'] + '.41')),
ObjectType(ObjectIdentity(myOIDs['if_out'] + '.41'))
)
in_out = getObjs(getoids)
if in_out:
timestamp = datetime.now()
net_history_data.append({
"timestamp": timestamp,
"net_in": in_out[0],
"net_out": in_out[1]
})
else:
print("Failed to retrieve network data")
time.sleep(10)
threading.Thread(target=update_net_history, daemon=True).start()
@app.route('/net_h/')
def net_history():
net_in = [round(entry["net_in"] / (1024 * 1024), 2) for entry in net_history_data]
net_out = [round(entry["net_out"] / (1024 * 1024), 2) for entry in net_history_data]
timestamps = [entry["timestamp"].strftime('%Y-%m-%d %H:%M:%S') for entry in net_history_data]
return {"net_in": net_in, "net_out": net_out, "timestamps": timestamps}
@app.route('/get_disk/')
def get_disk_usage():
getoids = (
ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.5.2')),
ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.5.1')),
ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.6.1')),
ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.6.2'))
)
results = getObjs(getoids)
total_part1 = results[0]
total_part2 = results[1]
used_part1 = results[2]
used_part2 = results[3]
if None not in [total_part1, total_part2, used_part1, used_part2]:
total = (total_part1 + total_part2) * 4096
used = (used_part1 + used_part2) * 4096
free = total - used
return {
'total': round(total / (1024 ** 3), 2),
'used': round(used / (1024 ** 3), 2),
'free': round(free / (1024 ** 3), 2)
}
else:
return None
def get_network_traffic():
in_bytes = getObjs([ObjectType(ObjectIdentity(myOIDs['if_in']+'.41'))])
return in_bytes[0] if in_bytes else 0
last_in_bytes = 0
@app.route('/volatility/')
def network_traffic_volatility():
global last_in_bytes
in_bytes= get_network_traffic()
volatility = in_bytes - last_in_bytes
last_in_bytes = in_bytes
return {'volatility': volatility}
if __name__ == '__main__':
app.run()
style.css
@charset "utf-8";
/* CSS Document */
*{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box}
*,body{padding:0px; margin:0px;font-family: "微软雅黑";}
body{color:#2c3e50;font-size: 16px; background: #fff;}
html,body{height: 100%;}
li{ list-style-type:none;}
i{ margin:0px; padding:0px; text-indent:0px;}
img{ border:none; max-width: 100%;}
a{ text-decoration:none; color:#34495e;}
a.active,a:focus{ outline:none!important; text-decoration:none;}
ol,ul,p,h1,h2,h3,h4,h5,h6{ padding:0; margin:0}
a:hover{ color:#3498db; text-decoration: none!important}
.clearfix:after, .clearfix:before {display: table;content: " "}
.clearfix:after {clear: both}
.pulll_left{float:left;}
.pulll_right{float:right;}
i{font-style: normal;}
.text-w{color: #f1c40f}
.text-d{color: #e67e22}
.text-s{color: #2ecc71}
.text-b{color: #3498db}
.head{position: relative; height: 90px; margin: 0 15px; padding-right: 60px;}
.head h1{ font-size: 30px; letter-spacing: -2px; text-align: center; line-height: 90px; padding-right: 55px; color: #3498db;}
.head .menu ul{ font-size: 0;}
.head .menu li{ display: inline-block; position: relative;margin: 25px 15px;;}
.head .menu li a{ display: block; font-size: 18px; color: #34495e; line-height: 40px; padding: 0 15px; }
.head .time{position: absolute; right: 0; line-height: 90px;}
.menu li:before,
.menu li:after{ position:absolute; width:10px; height:5px;opacity: .4; content: ""; border-top: 2px solid #3498db; top: -1px;border-radius: 2px;}
.menu li:before,.menu li a:before{border-left: 2px solid #3498db;left: -1px;}
.menu li:after,.menu li a:after{border-right: 2px solid #3498db; right: -1px;}
.menu li a{ position:relative;}
.menu li a:before,
.menu li a:after{ position:absolute; width:10px; height:5px; opacity: .4; content: "";border-bottom: 2px solid #3498db; bottom:-1px;border-radius: 2px;}
.head .menu li a:hover{ color: #3498db;}
.menu li a:hover:before,
.menu li a:hover:after,
.menu li:hover:before,
.menu li:hover:after{border-color: #3498db; opacity: 1;}
.mainbox{padding: 0px 10px;}
.nav1{margin-left: -6px; margin-right:-6px;}
.nav1>li{padding:0 6px; float: left;}
.box{ border:1px solid rgba(52,152,219,.5); box-shadow:inset 0 0 10px rgba(52,152,219,.4); margin-bottom: 12px; position: relative;}
.tit{ padding: 10px 10px 10px 25px;border-bottom:1px solid rgba(52,152,219,.7);font-size: 16px; font-weight: 500; position: relative;}
.tit:before,.tit01:before{position: absolute; content: ""; width: 6px; height: 6px; background: rgba(52,152,219,.9);box-shadow: 0 0 5px rgba(52,152,219,.9); border-radius: 10px; left: 10px; top: 18px;}
.tit:after,.box:before{ width: 100%; height: 1px; content: ""; position: absolute; left: 0; bottom:-1px; background:linear-gradient(to right,#3498db,#2980b9,#3498db); box-shadow: 0 0 5px rgba(52,152,219,1); opacity: .6}
.box:before{top: -1px;}
.boxnav{padding: 10px;}
.nav2>li:first-child{border:none;}
.nav2>li{float: left;border-left:1px solid rgba(52,152,219,.2); height:240px; padding: 0 10px 10px 10px;}
.tit01{font-size: 16px; font-weight: 500; position: relative; padding-left: 15px;}
.tit01:before{ left: 3px; top: 8px;}
.ftechart{height: 200px;}
.table1 th{ border-bottom: 1px solid #3498db; font-size: 14px; text-align: center; padding: 6px 0; color: rgba(44,62,80,.9)}
.table1 td{ border-bottom: 1px dotted #3498db;font-size: 12px; padding:6px 0;text-align: center; color: rgba(44,62,80,.7)}
.table1 tr:last-child td{border: none;}
.mapc{background: url(../images/bg3.png) no-repeat center center; background-size: 100% 100%}
.map{position: relative; height: 100%; padding-left: 10%;}
.mapnav{position: absolute;z-index: 10;}
.mapnav div{ background: url(../images/bg1.png) no-repeat; background-size:100% auto; width: 110px;text-align: center; padding: 20px 0; line-height: 120%;}
.mapnav div span{font-size: 14px; opacity: .6}
.mapnav div p{font-size: 20px; font-weight: bold; padding-top: 5px;}
.mapnav li{float: left; margin-right: 6px;}
.leidanav{margin-top: -5px;}
.leidanav li{float: left; width: 20%; text-align: center; border-left: 1px solid rgba(52,152,219,.1)}
.leidanav2 li{ width: 33.3333%}
.leidanav3 li{ width: 25%}
.leidanav li:first-child{border-left: none;}
.leidanav span{font-size: 12px; opacity: .6}
.leidanav p{font-size: 18px; color: #3498db }
.mapnav2{ position: absolute; left: 10px; bottom:0px; width: 40%; z-index: 10;}
.ybp{width: 100%}
.ybp li{float: left; width: 50%; height: 120px; }
.duibi li{float: left; width: 25%; height: 200px; padding: 0; border: none;}
.btn{ position: absolute; border-radius:2px; padding:4px 20px; opacity: .8;}
.btn1{border: 1px solid rgba(52,152,219,.5); background: #27ae60; left:35%; top: 30%;}
.btn2{ border: 1px solid rgba(52,152,219,.5); background: #2980b9;right:32%; top: 60%;}
.btn:hover{color: #fff; opacity:1;}
.btn1:before,.btn2:before{position: absolute; content: ''; width: 50px; height: 1px; background: #2c3e50;}
.btn1:before{ transform: rotate(30deg); right: -65%; top: 100%}
.btn2:before{ transform: rotate(30deg); left: -65%; top: -10%}
.tit02{font-size: 14px; padding: 10px 0;}
.water-container {
position: relative;
text-align: center;
}
.circle {
position: relative;
width: 150px;
height: 150px;
border-radius: 50%;
overflow: hidden;
background: #f0f0f0;
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
}
.water {
position: absolute;
bottom: 0;
width: 100%;
height: 100%;
background: #4da6ff;
animation: wave 2s infinite linear;
transform: translateY(70%);
}
.text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20px;
font-weight: bold;
color: #333;
}
.label {
margin-top: 10px;
font-size: 16px;
color: #888;
}
/* 波浪动画 */
@keyframes wave {
from {
transform: translateY(70%);
}
to {
transform: translateY(65%);
}
}
.tagcloud {
width:100%;
height:90%!important;
overflow: hidden;
position: relative;
}
.tagcloud a {
display: block;
border-radius: 50%;
color: #2c3e50;
font-weight: bold;
font-size: 14px;
text-decoration: none;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.b01{ width: 50px; height: 50px; }
.b02{ width: 80px; height: 80px; }
.b03{ width: 60px; height: 60px; }
.b04{ width: 70px; height: 70px; }
.co01{ border: 2px solid rgba(52,152,219,1); box-shadow: inset 0 0 20px rgba(52,152,219,1);}
.co02{ border: 2px solid rgba(241,196,15,1); box-shadow: inset 0 0 20px rgba(241,196,15,1);}
.co03{ border: 2px solid rgba(41,128,185,1); box-shadow: inset 0 0 20px rgba(41,128,185,1);}
.co04{ border: 2px solid rgba(46,204,113,1); box-shadow: inset 0 0 20px rgba(46,204,113,1);}
.co05{ border: 2px solid rgba(230,126,34,1); box-shadow: inset 0 0 20px rgba(230,126,34,1);}
.huati{ padding-top: 20px;}
.huati li{ font-size: 12px; line-height: 230%;}
.wancheng{display: flex; align-items: center; justify-content: center;}
.wancheng span{font-size: 14px; color: #2c3e50;}
.wancheng h3{font-size: 20px; color:#3498db;}
.wancheng h3 i{font-size: 12px; color:#2c3e50;}
.yuan{padding:5px;border-radius: 100%; margin-left: 10px; border: 2px solid rgba(52,152,219,.8);}
.yuan span{width: 60px; height: 60px; border-radius: 100%; background: rgba(52,152,219,.8); display: flex; align-items: center; justify-content: center; font-size: 20px;}