Browse Source

基本实现了内存、存储攻坚、GPU的显示

v2
lxb 8 months ago
parent
commit
fd3d5b1959
  1. 4
      client.py
  2. 58
      web/css/style_1.css
  3. 7
      web/index.html
  4. 180
      web/js/script.js

4
client.py

@ -112,8 +112,8 @@ def get_memory_info(error_dict):
result_dict = dict()
try:
mem = psutil.virtual_memory()
result_dict["total"] = mem.total
result_dict["used"] = mem.used
result_dict["total"] = mem.total / 1024
result_dict["used"] = mem.used / 1024
except Exception as e:
error_dict['memory'] = e

58
web/css/style_1.css

@ -0,0 +1,58 @@
#header-container {
background-color: beige;
}
.card {
border-style: solid;
border-width: 2px;
border-color: black;
/* background-color: aqua; */
padding: 5px;
margin: 5px;
border-radius: 8px;
}
.server-name {
background-color: black;
color: white;
border-radius: 8px;
padding: 4px 10px;
font-size: 26px;
}
.gpu-info {
/* background-color: aqua; */
border-style: solid;
border-width: 1px;
border-color: #ccc;
border-radius: 8px;
margin-top: 5px;
padding: 4px 8px;
margin-bottom: 5px;
background-color: #f9f9f9;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.process-item {
color: rgb(26, 92, 247);
font-weight: bold;
}
/*占用状态*/
.state-free {
color: green;
}
.state-occupy {
color: red;
}
.state-light-occupy {
color: orange;
}
.state-super-occupy {
color: rgb(255, 0, 0);
font-weight: bold;
font-size: 20px;
background-color: rgb(255, 255, 0);
border-radius: 8px;
padding: 1px 6px;
}

7
web/index.html

@ -4,8 +4,15 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>服务器信息</title>
<link rel="stylesheet" href="./css/style_1.css">
</head>
<body>
<div id="header-container">
服务器信息
</div>
<div id="server-data">
</div>
<script src="./js/script.js"></script>
</body>
</html>

180
web/js/script.js

@ -0,0 +1,180 @@
// 请求服务器获取数据
function fetchData() {
fetch('http://127.0.0.1:15002/api/get_data')
// 获取服务器和显卡数据
.then(response => response.json()) // 解析 JSON 响应
.then(data => {
// 处理 JSON 数据
// console.log(data);
displayServerData(data); // 调用显示数据的函数
})
.catch(error => {
// console.error('Error fetching data:', error);
displayError(error + " (多半是没有正确连接服务器端,可能是没开、网络错误)");
});
}
// 显示错误
function displayError(err_info){
let serverDataContainer = document.getElementById('server-data');
serverDataContainer.innerHTML = ''; // 清空容器
let errDiv = document.createElement('div');
errDiv.classList.add('error-info');
errDiv.innerText = err_info;
serverDataContainer.appendChild(errDiv);
}
// 将KB转为合适的格式
function parse_data_unit(num, fixedLen=2){
if (num < 1024){
return num.toFixed(fixedLen) + " KB";
}
num /= 1024;
if (num < 1024){
return num.toFixed(fixedLen) + " MB";
}
num /= 1024;
if (num < 1024){
return num.toFixed(fixedLen) + " GB";
}
num /= 1024;
if (num < 1024){
return num.toFixed(fixedLen) + " TB";
}
}
function add_bar(serverCard){
let bar = document.createElement('hr');
serverCard.appendChild(bar);
}
// 添加服务器信息的元素
function displayServerData(data){
let serverDataContainer = document.getElementById('server-data');
serverDataContainer.innerHTML = ''; // 清空容器
let serverDataDict = data['server_dict'];
// 创建每一个服务器的信息
for (let serverTitle in serverDataDict){
let serverCard = document.createElement('div');
serverCard.className = 'card';
// 标题
let serverName = document.createElement('div');
serverName.className = 'server-name';
serverName.textContent = serverTitle;
serverCard.appendChild(serverName);
serverData = serverDataDict[serverTitle];
// 如果没有数据则跳过
if (serverData == null){
let errText = document.createElement('div');
errText.className = 'error-text';
errText.textContent = "No data.";
serverCard.appendChild(errText);
serverDataContainer.appendChild(serverCard);
continue;
}
// 内存
if ('memory' in serverData){
let memoryInfo = document.createElement('div');
memoryInfo.className = 'memory-info';
let totalNum = serverData.memory.total
let usedNum = serverData.memory.used
let totalMem = parse_data_unit(totalNum);
let usedMem = parse_data_unit(usedNum);
let tmpClass = "state-free";
if (usedNum / totalNum > 0.95)
tmpClass = "state-super-occupy";
else if (usedNum / totalNum > 0.8)
tmpClass = "state-occupy";
else if (usedNum / totalNum > 0.6)
tmpClass = "state-light-occupy";
memoryInfo.innerHTML += "<strong> 内存 : </strong> <span class=\"" + tmpClass + "\">" + usedMem + " / " + totalMem + "</span><br>";
serverCard.appendChild(memoryInfo);
// 分割线
add_bar(serverCard);
}
// 存储空间
if ('storage_list' in serverData){
let storageInfo = document.createElement('div');
storageInfo.className = 'storage-info';
for (let i = 0; i < serverData.storage_list.length; i++) {
let targetPath = serverData.storage_list[i].path;
let totalNum = serverData.storage_list[i].total
let availableNum = serverData.storage_list[i].available
let totalStorage = parse_data_unit(totalNum);
let availableStorage = parse_data_unit(totalNum - availableNum);
let tmpClass = "state-free";
if (availableNum / totalNum < 0.01)
tmpClass = "state-super-occupy";
else if (availableNum / totalNum < 0.1)
tmpClass = "state-occupy";
else if (availableNum / totalNum < 0.3)
tmpClass = "state-light-occupy";
storageInfo.innerHTML += '<strong>' + targetPath + " :</strong> <span class=\"" + tmpClass
+ "\">" + availableStorage + " / " + totalStorage + "</span><br>";
}
serverCard.appendChild(storageInfo);
// 分割线
add_bar(serverCard);
}
if ('gpu_list' in serverData){
serverData.gpu_list.forEach(function(gpu){
let gpuInfo = document.createElement('div');
gpuInfo.className = 'gpu-info';
let markFree = '<span class="state-free"> 空闲</span>';
let markLightOccupy = '<span class="state-light-occupy"> 占用</span>';
let markOccupy = '<span class="state-occupy"> 占用</span>';
let tmpMark = markFree;
if (gpu.used_memory < 1000 && gpu.utilization < 20){
tmpMark = markFree;
}
else if (gpu.util_mem < 50){
tmpMark = markLightOccupy;
}else{
tmpMark = markOccupy;
}
gpuInfo.innerHTML = '<strong>' + gpu.idx + ' - ' + gpu.name + tmpMark + '</strong><br>'
+ '温度: ' + gpu.temperature + '°C<br>'
+ '显存: ' + gpu.used_memory + ' / ' + gpu.total_memory + " MB" + '<br>'
+ '利用率: ' + gpu.utilization + '%';
// 添加进程信息
let processInfo = document.createElement('div');
processInfo.classList.add('process-info');
processInfo.innerHTML = "<strong>使用情况:</strong>";
gpu.process_list.sort((a, b) => b.memory - a.memory);
gpu.process_list.forEach(function(item, index){
console.log(item.memory );
if (item.memory > 40)
processInfo.innerHTML += `<span class="process-item" title="${item.cmd}">${item.user} (${item.memory}) </span>`;
});
gpuInfo.appendChild(processInfo); // 将用户信息添加到GPU信息中
serverCard.appendChild(gpuInfo);
});
// 分割线
add_bar(serverCard);
}
// 单个服务器信息作为child加入
serverDataContainer.appendChild(serverCard);
}
}
// TODO test
fetchData()
Loading…
Cancel
Save