Compare commits
14 Commits
0eb99ecd74
...
c04ed36469
Author | SHA1 | Date |
---|---|---|
|
c04ed36469 | 2 months ago |
|
68c7e30a18 | 4 months ago |
|
98a56aa10c | 4 months ago |
|
bd14256375 | 4 months ago |
|
374b5ccdcf | 5 months ago |
|
0fbf3d3f8d | 5 months ago |
|
4d8f4635d4 | 7 months ago |
|
06dda28776 | 7 months ago |
|
26d44f3e6c | 7 months ago |
|
5774ea3da9 | 7 months ago |
|
73384032a0 | 8 months ago |
|
9f4e8c7db3 | 8 months ago |
|
b3dbda6157 | 8 months ago |
|
637fc387aa | 8 months ago |
13 changed files with 297 additions and 455 deletions
@ -1 +1,6 @@ |
|||||
serverList.json |
serverList.json |
||||
|
|
||||
|
# build |
||||
|
build/ |
||||
|
dist/ |
||||
|
*.spec |
Binary file not shown.
@ -1,317 +0,0 @@ |
|||||
<!DOCTYPE html> |
|
||||
<html lang="en"> |
|
||||
<head> |
|
||||
<meta charset="UTF-8"> |
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
||||
<title>Server and GPU Information</title> |
|
||||
<style> |
|
||||
.card { |
|
||||
margin: 10px; |
|
||||
padding: 10px; |
|
||||
border: 1px solid #ccc; |
|
||||
border-radius: 5px; |
|
||||
width: 300px; |
|
||||
display: inline-block; |
|
||||
vertical-align: top; |
|
||||
} |
|
||||
.server-name { |
|
||||
font-weight: bold; |
|
||||
margin-bottom: 5px; |
|
||||
font-size: 24px; /* 调整字体大小 */ |
|
||||
background-color: black; /* 背景色设为黑色 */ |
|
||||
color: white; /* 文字颜色设为白色 */ |
|
||||
padding: 10px; /* 增加内边距使其更美观 */ |
|
||||
border-radius: 5px; /* 可选:增加圆角效果 */ |
|
||||
} |
|
||||
.gpu-info { |
|
||||
margin-top: 10px; |
|
||||
border: 1px solid #ccc; /* 边框 */ |
|
||||
border-radius: 8px; /* 圆角 */ |
|
||||
padding: 10px; /* 内边距 */ |
|
||||
margin-bottom: 15px; /* 下边距 */ |
|
||||
background-color: #f9f9f9; /* 背景颜色 */ |
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 阴影 */ |
|
||||
} |
|
||||
|
|
||||
.user-info { |
|
||||
margin-top: 10px; /* 上边距 */ |
|
||||
font-size: 14px; /* 字体大小 */ |
|
||||
color: #555; /* 字体颜色 */ |
|
||||
} |
|
||||
|
|
||||
.user-item { |
|
||||
color: #007bff; /* 用户名颜色 */ |
|
||||
font-weight: bold; /* 加粗 */ |
|
||||
} |
|
||||
|
|
||||
/* 头部样式 */ |
|
||||
.head_contrainer{ |
|
||||
display: flex; |
|
||||
flex-direction: row; |
|
||||
justify-content: space-between; |
|
||||
height: 90px; |
|
||||
align-items: center; |
|
||||
} |
|
||||
.head_contrainer .checkboxes{ |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
</style> |
|
||||
</head> |
|
||||
<body> |
|
||||
<div class="head_contrainer"> |
|
||||
<div> |
|
||||
<h1>Server and GPU Information</h1> |
|
||||
<p id="time"></p> |
|
||||
</div> |
|
||||
|
|
||||
<div class="checkboxes"> |
|
||||
<div class="sample"> |
|
||||
<label for="toggle_network">网络</label> |
|
||||
<input type="checkbox" id="toggle_network" checked onchange="updateDisplay()"> |
|
||||
</div> |
|
||||
<div class="sample"> |
|
||||
<label for="toggle_memory">内存</label> |
|
||||
<input type="checkbox" id="toggle_memory" checked onchange="updateDisplay()"> |
|
||||
</div> |
|
||||
<div class="sample"> |
|
||||
<label for="toggle_storage">存储</label> |
|
||||
<input type="checkbox" id="toggle_storage" checked onchange="updateDisplay()"> |
|
||||
</div> |
|
||||
<div class="sample"> |
|
||||
<label for="toggle_gpus">显卡</label> |
|
||||
<input type="checkbox" id="toggle_gpus" checked onchange="updateDisplay()"> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div id="server-data"></div> |
|
||||
|
|
||||
<script> |
|
||||
let lastData = null; |
|
||||
|
|
||||
// 请求服务器获取GPus数据 |
|
||||
function fetchData() { |
|
||||
fetch('http://127.0.0.1:15002/all_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.innerHTML = err_info; |
|
||||
serverDataContainer.appendChild(errDiv); |
|
||||
} |
|
||||
|
|
||||
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 updateDisplay(){ |
|
||||
if (lastData != null){ |
|
||||
displayServerData(lastData); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 页面绑定数据 |
|
||||
function displayServerData(data) { |
|
||||
lastData = data; |
|
||||
// 绘制 ------------------- |
|
||||
let serverDataContainer = document.getElementById('server-data'); |
|
||||
serverDataContainer.innerHTML = ''; // 清空容器 |
|
||||
|
|
||||
let timeStr = data['time'] |
|
||||
let serverData = data['server_data'] |
|
||||
|
|
||||
let timeDiv = document.getElementById('time') |
|
||||
timeDiv.textContent = "更新时间为:" + timeStr |
|
||||
|
|
||||
let greenDot = '<span style="color: green;"> 空闲</span>'; |
|
||||
let yellowDot = '<span style="color: orange;"> 占用</span>'; |
|
||||
let redDot = '<span style="color: red;"> 占用</span>'; |
|
||||
|
|
||||
for (let key in serverData){ |
|
||||
let serverCard = document.createElement('div'); |
|
||||
serverCard.classList.add('card'); |
|
||||
|
|
||||
// 标题 |
|
||||
let serverName = document.createElement('div'); |
|
||||
serverName.classList.add('server-name'); |
|
||||
let updateFlag = serverData[key].updated ? '' : ' - Not updated -'; |
|
||||
serverName.textContent = key + updateFlag; |
|
||||
serverCard.appendChild(serverName); |
|
||||
|
|
||||
// 网速 |
|
||||
if (document.getElementById('toggle_network').checked && 'network_info' in serverData[key]){ |
|
||||
let networkInfo = document.createElement('div'); |
|
||||
networkInfo.classList.add('network-info'); |
|
||||
|
|
||||
let inNum = serverData[key].network_info.in; |
|
||||
let outNum = serverData[key].network_info.out; |
|
||||
inNum = parse_data_unit(inNum) |
|
||||
outNum = parse_data_unit(outNum) |
|
||||
|
|
||||
networkInfo.innerHTML += "<strong> 网络 : </strong> in: " + inNum + "/s, out: " + outNum + "/s"; |
|
||||
|
|
||||
serverCard.appendChild(networkInfo); |
|
||||
// 分割线 |
|
||||
add_bar(serverCard); |
|
||||
} |
|
||||
|
|
||||
// 内存 |
|
||||
if (document.getElementById('toggle_memory').checked && 'memory_info' in serverData[key]){ |
|
||||
let memoryInfo = document.createElement('div'); |
|
||||
memoryInfo.classList.add('memory-info'); |
|
||||
|
|
||||
let totalNum = serverData[key].memory_info.total |
|
||||
let usedNum = serverData[key].memory_info.used |
|
||||
let totalMem = parse_data_unit(totalNum); |
|
||||
let usedMem = parse_data_unit(usedNum); |
|
||||
let tmpColor = "green"; |
|
||||
if (usedNum / totalNum > 0.8) |
|
||||
tmpColor = "red"; |
|
||||
else if (usedNum / totalNum > 0.6) |
|
||||
tmpColor = "orange"; |
|
||||
|
|
||||
memoryInfo.innerHTML += "<strong> 内存 : </strong> <span style=\"color: " + tmpColor + ";\">" + usedMem + " / " + totalMem + "</span><br>"; |
|
||||
|
|
||||
serverCard.appendChild(memoryInfo); |
|
||||
// 分割线 |
|
||||
add_bar(serverCard); |
|
||||
} |
|
||||
|
|
||||
// 存储空间 |
|
||||
if (document.getElementById('toggle_storage').checked && 'storage_info_list' in serverData[key]){ |
|
||||
let storageInfo = document.createElement('div'); |
|
||||
storageInfo.classList.add('storage-info'); |
|
||||
|
|
||||
for (let i = 0; i < serverData[key].storage_info_list.length; i++) { |
|
||||
let targetPath = serverData[key].storage_info_list[i].path; |
|
||||
let totalNum = serverData[key].storage_info_list[i].total |
|
||||
let availableNum = serverData[key].storage_info_list[i].available |
|
||||
let totalStorage = parse_data_unit(totalNum); |
|
||||
let availableStorage = parse_data_unit(totalNum - availableNum); |
|
||||
let tmpColor = "green"; |
|
||||
if (availableNum / totalNum < 0.1) |
|
||||
tmpColor = "red"; |
|
||||
else if (availableNum / totalNum < 0.3) |
|
||||
tmpColor = "orange"; |
|
||||
storageInfo.innerHTML += '<strong>' + targetPath + " :</strong> <span style=\"color: " + tmpColor |
|
||||
+ ";\">" + availableStorage + " / " + totalStorage + "</span><br>"; |
|
||||
} |
|
||||
|
|
||||
serverCard.appendChild(storageInfo); |
|
||||
// 分割线 |
|
||||
add_bar(serverCard); |
|
||||
} |
|
||||
|
|
||||
// gpu |
|
||||
if (document.getElementById('toggle_gpus').checked && 'gpu_info_list' in serverData[key]){ |
|
||||
serverData[key].gpu_info_list.forEach(function(gpu){ |
|
||||
let gpuInfo = document.createElement('div'); |
|
||||
gpuInfo.classList.add('gpu-info'); |
|
||||
let colorDot = greenDot; |
|
||||
if (gpu.used_mem < 1000 && gpu.util_gpu < 20){ |
|
||||
colorDot = greenDot; |
|
||||
} |
|
||||
else if (gpu.util_mem < 50){ |
|
||||
colorDot = yellowDot; |
|
||||
}else{ |
|
||||
colorDot = redDot; |
|
||||
} |
|
||||
gpuInfo.innerHTML = '<strong>' + gpu.idx + ' - ' + gpu.gpu_name + colorDot + '</strong><br>' |
|
||||
+ '温度: ' + gpu.temperature + '°C<br>' |
|
||||
+ '显存: ' + gpu.used_mem + ' / ' + gpu.total_mem + " MB" + '<br>' |
|
||||
+ '利用率: ' + gpu.util_gpu + '%'; |
|
||||
|
|
||||
// 添加用户使用信息 |
|
||||
if ('users' in gpu) { // 检查是否有用户信息 |
|
||||
let userInfo = document.createElement('div'); |
|
||||
userInfo.classList.add('user-info'); |
|
||||
userInfo.innerHTML = "<strong>使用情况:</strong>"; |
|
||||
|
|
||||
// for (const [username, mem] of Object.entries(gpu.users)) { |
|
||||
// userInfo.innerHTML += `<span class="user-item">${username} (${mem}) </span>`; |
|
||||
// } |
|
||||
// 排序 |
|
||||
const user_entries = Object.entries(gpu.users); |
|
||||
const sorted_user = user_entries.sort((a, b) => b[1] - a[1]); |
|
||||
sorted_user.forEach(([key, value]) => { |
|
||||
// 过滤小于50MB的 |
|
||||
if (value > 40) |
|
||||
userInfo.innerHTML += `<span class="user-item">${key} (${value}) </span>`; |
|
||||
}); |
|
||||
|
|
||||
gpuInfo.appendChild(userInfo); // 将用户信息添加到GPU信息中 |
|
||||
} |
|
||||
|
|
||||
serverCard.appendChild(gpuInfo); |
|
||||
}); |
|
||||
// 分割线 |
|
||||
add_bar(serverCard); |
|
||||
} |
|
||||
|
|
||||
// 错误信息 |
|
||||
if ('err_info' in serverData[key]) |
|
||||
{ |
|
||||
let errInfo = document.createElement('div'); |
|
||||
errInfo.classList.add('error-info'); |
|
||||
errInfo.innerHTML = '<strong>error info</strong><br>' + serverData[key].err_info; |
|
||||
serverCard.appendChild(errInfo); |
|
||||
// 分割线 |
|
||||
add_bar(serverCard); |
|
||||
} |
|
||||
|
|
||||
// 删除最后的分割线 |
|
||||
if (serverCard.lastElementChild && serverCard.lastElementChild.tagName === 'HR') { |
|
||||
serverCard.removeChild(serverCard.lastElementChild); |
|
||||
} |
|
||||
|
|
||||
serverDataContainer.appendChild(serverCard); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 页面加载时获取数据并定时刷新 |
|
||||
document.addEventListener('DOMContentLoaded', function() { |
|
||||
fetchData(); |
|
||||
setInterval(fetchData, 3000); // 每3秒刷新一次数据 |
|
||||
}); |
|
||||
</script> |
|
||||
</body> |
|
||||
</html> |
|
Before Width: | Height: | Size: 754 KiB After Width: | Height: | Size: 754 KiB |
@ -1,8 +1,8 @@ |
|||||
{ |
{ |
||||
"host": "127.0.0.1", |
"host": "0.0.0.0", |
||||
"port": 15002, |
"port": 15002, |
||||
"server_list":["76", "174", "233", "222"], |
"server_list":["76", "174", "233", "222"], |
||||
"note_dict":{ |
"note_dict":{ |
||||
"174": "test note" |
}, |
||||
} |
"api_name": "api" |
||||
} |
} |
@ -0,0 +1 @@ |
|||||
|
version = "0.1.1.20250317_beta" |
@ -1,18 +1,27 @@ |
|||||
<!DOCTYPE html> |
<!DOCTYPE html> |
||||
<html lang="en"> |
<html lang="en"> |
||||
|
|
||||
<head> |
<head> |
||||
<meta charset="UTF-8"> |
<meta charset="UTF-8"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<title>服务器信息</title> |
<title>服务器信息</title> |
||||
<link rel="stylesheet" href="./css/style_1.css"> |
<link rel="stylesheet" href="./css/style_1.css"> |
||||
</head> |
</head> |
||||
|
|
||||
<body> |
<body> |
||||
<div id="header-container"> |
<div class="content"> |
||||
服务器信息 |
<div id="header-container"> |
||||
</div> |
服务器信息 |
||||
<div id="server-data"> |
</div> |
||||
|
<div id="server-data"> |
||||
|
</div> |
||||
</div> |
</div> |
||||
|
|
||||
|
<footer> |
||||
|
<p>项目源码在<a href="http://git.lxblxb.top/lxb/Tool_CheckGPUsWeb/src/branch/v2">这里</a>,有问题可联系<span title="xiongbin_lin@163.com">lxb</span>。</p> |
||||
|
</footer> |
||||
|
|
||||
<script src="./js/script.js"></script> |
<script src="./js/script.js"></script> |
||||
</body> |
</body> |
||||
|
|
||||
</html> |
</html> |
Loading…
Reference in new issue