feat: 磁盘分区列 — 多分区/进度条/overflow/过滤虚拟FS
SystemInfoCollector: - _get_partitions(): psutil disk_partitions + 过滤虚拟FS - 跳过 tmpfs/devtmpfs/proc/sysfs/cgroup等22种 - 无psutil时 fallback到根分区 前端4列: 160px 1fr 0.8fr 1fr - col-disk: 分区名/挂载点/进度条/百分比 - max-height:200px overflow:auto - 跨平台兼容 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -56,13 +56,22 @@
|
||||
.node-notes { font-size:.75rem; color:var(--text-dim); font-style:italic; margin-bottom:8px }
|
||||
/* 横版布局 — 左设备信息 | 右数据+图表同行 */
|
||||
#sentinel-grid.layout-row { display:flex;flex-direction:column;gap:12px }
|
||||
#sentinel-grid.layout-row .node-card { display:grid;grid-template-columns:160px 1fr 1fr;gap:12px 16px;align-items:start }
|
||||
#sentinel-grid.layout-row .node-card { display:grid;grid-template-columns:160px 1fr 0.8fr 1fr;gap:12px 16px;align-items:start }
|
||||
#sentinel-grid.layout-row .col-left { min-width:0 }
|
||||
#sentinel-grid.layout-row .col-right-stack { display:flex;flex-direction:column;gap:12px;min-width:0 }
|
||||
#sentinel-grid.layout-row .col-extra { display:flex;flex-direction:column;gap:6px;padding:0 8px }
|
||||
#sentinel-grid.layout-row .extra-row { font-size:.8rem;padding:3px 0;border-bottom:1px solid var(--md-sys-color-surface-container-lowest) }
|
||||
#sentinel-grid.layout-row .extra-row .elabel { font-size:.65rem;color:var(--text-dim);text-transform:uppercase;margin-right:4px }
|
||||
#sentinel-grid.layout-row .extra-row .eval { font-weight:500 }
|
||||
#sentinel-grid.layout-row .col-disk { overflow-y:auto;max-height:200px;padding:0 4px }
|
||||
#sentinel-grid.layout-row .disk-list { display:flex;flex-direction:column;gap:4px }
|
||||
#sentinel-grid.layout-row .part-row { display:flex;flex-direction:column;gap:2px;padding:3px 0;border-bottom:1px solid var(--md-sys-color-surface-container-lowest) }
|
||||
#sentinel-grid.layout-row .part-info { display:flex;justify-content:space-between;font-size:.7rem }
|
||||
#sentinel-grid.layout-row .part-name { font-weight:500;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
|
||||
#sentinel-grid.layout-row .part-mount { color:var(--text-dim);font-size:.65rem }
|
||||
#sentinel-grid.layout-row .part-bar { height:3px;border-radius:1px;background:var(--md-sys-color-surface-container-lowest);margin:2px 0 }
|
||||
#sentinel-grid.layout-row .part-bar-fill { height:100%;border-radius:1px;background:var(--primary);transition:width .6s }
|
||||
#sentinel-grid.layout-row .part-pct { font-size:.6rem;color:var(--text-dim);text-align:right }
|
||||
#sentinel-grid.layout-row .mtr-data .rlabel { font-size:.7rem;color:var(--text-dim);text-transform:uppercase;margin-right:6px }
|
||||
#sentinel-grid.layout-row .mtr-data .rval { font-weight:600 }
|
||||
#sentinel-grid.layout-row .mtr { display:flex;align-items:center;height:48px;padding:0 8px;margin-bottom:6px;position:relative }
|
||||
@@ -201,11 +210,11 @@
|
||||
'<div class="col-extra">'+
|
||||
'<div class="extra-row"><span class="elabel">负载</span> <span class="eval load-val">—</span></div>'+
|
||||
'<div class="extra-row"><span class="elabel">SWAP</span> <span class="eval swap-val">—</span></div>'+
|
||||
'<div class="extra-row"><span class="elabel">磁盘</span> <span class="eval disk-val">—</span></div>'+
|
||||
'<div class="extra-row"><span class="elabel">温度</span> <span class="eval temp-val">—</span></div>'+
|
||||
'<div class="extra-row"><span class="elabel">流量</span> <span class="eval traf-val">—</span></div>'+
|
||||
'<div class="extra-row"><span class="elabel">进程</span> <span class="eval proc-val">—</span></div>'+
|
||||
'</div>';
|
||||
'</div>'+
|
||||
'<div class="col-disk"><div class="disk-list"></div></div>';
|
||||
} else {
|
||||
card.innerHTML =
|
||||
'<div class="node-name">'+(n.online?'🟢':'🔴')+' '+esc(n.name)+'</div>'+
|
||||
@@ -285,7 +294,26 @@
|
||||
var sysData = n.system || {};
|
||||
if (loadEl && sysData.cpu) loadEl.textContent = (sysData.cpu.load_avg||[0,0,0]).map(function(v){return v.toFixed(1);}).join(' / ');
|
||||
if (swapEl && sysData.swap) { var st = sysData.swap.total_gb||0; swapEl.textContent = st > 0 ? (sysData.swap.percent||0).toFixed(1)+'% ('+(sysData.swap.used_gb||0).toFixed(1)+'G)' : '—'; }
|
||||
if (diskEl && sysData.disk) { var dt = sysData.disk.total_gb||0; diskEl.textContent = dt > 0 ? (sysData.disk.percent||0).toFixed(1)+'% ('+(sysData.disk.used_gb||0).toFixed(1)+'/'+(sysData.disk.total_gb||0).toFixed(1)+'G)' : '—'; }
|
||||
// 磁盘分区列表
|
||||
var diskList = card.querySelector('.disk-list');
|
||||
if (diskList && sysData.partitions) {
|
||||
var parts = sysData.partitions || [];
|
||||
if (!diskList.querySelector('.part-row') || diskList.children.length !== parts.length) {
|
||||
diskList.innerHTML = parts.map(function(p){
|
||||
return '<div class="part-row"><div class="part-info"><span class="part-name">'+esc(p.device||'?')+'</span> <span class="part-mount">'+esc(p.mount||'')+'</span></div><div class="part-bar"><div class="part-bar-fill" style="width:'+(p.percent||0)+'%"></div></div><span class="part-pct">'+(p.percent||0).toFixed(0)+'%</span></div>';
|
||||
}).join('');
|
||||
} else {
|
||||
var rows = diskList.querySelectorAll('.part-row');
|
||||
parts.forEach(function(p, i){
|
||||
if (rows[i]) {
|
||||
var fill = rows[i].querySelector('.part-bar-fill');
|
||||
var pct = rows[i].querySelector('.part-pct');
|
||||
if (fill) fill.style.width = (p.percent||0)+'%';
|
||||
if (pct) pct.textContent = (p.percent||0).toFixed(0)+'%';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (tempEl && sysData.temperature) tempEl.textContent = (sysData.temperature.current||0) > 0 ? (sysData.temperature.current).toFixed(1)+'°C' : '—';
|
||||
if (trafEl && sysData.network) trafEl.textContent = '↓'+(sysData.network.rx_mb||0).toFixed(0)+'M ↑'+(sysData.network.tx_mb||0).toFixed(0)+'M';
|
||||
if (procEl && sysData.process) procEl.textContent = (sysData.process.memory_mb||0).toFixed(0)+'MB';
|
||||
|
||||
Reference in New Issue
Block a user