feat: add Linux PSI I/O pressure monitoring with real-time dashboard panel and auto-refresh on DOM mutations

Add io_pressure() function to parse /proc/pressure/io with line splitting, key-value extraction from some/full metrics, and OSError/ValueError exception handling returning available:False on failure. Add io_pressure() call to datastore_snapshot() return dict. Add DOMContentLoaded script to create #ioPressurePanel section with datastore-panel/io-pressure-panel classes, innerHTML with I/O-
This commit is contained in:
nessi committed 2026-08-17 19:21:49 +02:00
1 parent c6c2437732
commit b275164be9
2 files changed
+18 -2

No files matched your search

+4 -1
View File
@@ -1,6 +1,9 @@
<!doctype html>
<script>
document.addEventListener('DOMContentLoaded',()=>{const updateTemperatures=async()=>{const container=document.querySelector('#raidDisks');if(!container)return;try{const data=await (await fetch('/api/datastore')).json();const disks=data.raid?.devices||[];container.querySelectorAll('.raid-disk').forEach(row=>{const device=row.querySelector('strong')?.textContent.trim();const disk=disks.find(item=>item.device===device);if(!disk)return;let node=row.querySelector('.raid-temperature');if(!node){node=document.createElement('small');node.className='raid-temperature';const smart=row.querySelector('.raid-smart');if(smart)smart.after(node);else row.querySelector('div')?.append(node)}node.textContent=`Temperatur: ${disk.temperature||'Nicht verfügbar'}`})}catch(error){}};updateTemperatures();setInterval(updateTemperatures,5000)});
document.addEventListener('DOMContentLoaded',()=>{const container=document.querySelector('#raidDisks');if(!container)return;const refresh=async()=>{try{const devices=(await (await fetch('/api/datastore')).json()).raid?.devices||[];container.querySelectorAll('.raid-disk').forEach(row=>{const disk=devices.find(item=>item.device===row.querySelector('strong')?.textContent.trim());if(!disk)return;let node=row.querySelector('.raid-temperature');if(!node){node=document.createElement('small');node.className='raid-temperature';row.querySelector('.raid-smart')?.after(node)}node.textContent=`Temperatur: ${disk.temperature||'Nicht verfügbar'}`})}catch(error){}};const observer=new MutationObserver(records=>{if(records.some(record=>record.target===container))setTimeout(refresh,0)});observer.observe(container,{childList:true,subtree:true});refresh()});
</script>
<script>
document.addEventListener('DOMContentLoaded',()=>{const root=document.querySelector('#datastore');if(!root)return;const grid=root.querySelector('.datastore-grid');if(grid&&!document.querySelector('#ioPressurePanel')){const panel=document.createElement('section');panel.id='ioPressurePanel';panel.className='datastore-panel io-pressure-panel';panel.innerHTML='<div class="datastore-panel-head"><div><h3>I/O-Auslastung</h3><p>Festplatten-Druck aus Linux PSI</p></div><strong id="ioPressureLabel">Wird geladen …</strong></div><div class="io-pressure-bars"><div><span>Some</span><b id="ioPressureSome">—</b><div class="datastore-progress"><span id="ioPressureSomeBar"></span></div></div><div><span>Full</span><b id="ioPressureFull">—</b><div class="datastore-progress"><span id="ioPressureFullBar"></span></div></div></div>';grid.before(panel)}const pressure=async()=>{try{const data=await (await fetch('/api/datastore')).json();const io=data.io_pressure||{};const some=Number(io.some?.avg10)||0,full=Number(io.full?.avg10)||0;const level=Math.max(some,full),label=level>=20?'Hoch':level>=5?'Beobachten':'Normal';const set=(id,value)=>{const node=document.querySelector(id);if(node)node.textContent=value};set('#ioPressureLabel',io.available?`${label} · ${level.toFixed(1)}%`:'Nicht verfügbar');set('#ioPressureSome',`${some.toFixed(1)}%`);set('#ioPressureFull',`${full.toFixed(1)}%`);const a=document.querySelector('#ioPressureSomeBar'),b=document.querySelector('#ioPressureFullBar');if(a)a.style.width=`${Math.min(100,some)}%`;if(b)b.style.width=`${Math.min(100,full)}%`}catch(error){}};pressure();setInterval(pressure,5000);const disks=document.querySelector('#raidDisks');if(disks){const observer=new MutationObserver(()=>{if([...disks.querySelectorAll('.raid-disk')].some(row=>!row.querySelector('.raid-temperature')))setTimeout(pressure,0)});observer.observe(disks,{childList:true,subtree:true})}});
</script>
<script>
if ('serviceWorker' in navigator) {