Skip to content

Commit b178d3e

Browse files
authored
add detailed process info (#2761)
1 parent 2372884 commit b178d3e

3 files changed

Lines changed: 105 additions & 9 deletions

File tree

web/maintenance/style.css

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ h1 {
3333
margin-bottom: 12px;
3434
}
3535
.card table {
36-
width: 100%; /* wieder volle Kartenbreite */
37-
max-width: 100%; /* wieder volle Kartenbreite */
36+
width: 100%; /* wieder volle Kartenbreite */
37+
max-width: 100%; /* wieder volle Kartenbreite */
3838
}
3939
table {
4040
border-collapse: collapse;
@@ -66,3 +66,57 @@ th {
6666
align-items: center;
6767
margin-right: 30px;
6868
}
69+
70+
/* Modal Overlay */
71+
.details-modal {
72+
display: none;
73+
position: fixed;
74+
left: 0;
75+
top: 0;
76+
width: 100vw;
77+
height: 100vh;
78+
background: rgba(0, 0, 0, 0.4);
79+
align-items: center;
80+
justify-content: center;
81+
z-index: 10000;
82+
}
83+
84+
/* Modal Inhalt */
85+
.details-modal-content {
86+
background: #fff;
87+
padding: 24px 32px;
88+
border-radius: 8px;
89+
max-width: 90vw;
90+
max-height: 80vh;
91+
box-shadow: 0 2px 16px #0003;
92+
position: relative;
93+
display: flex;
94+
flex-direction: column;
95+
}
96+
97+
/* Modal Nachricht */
98+
#details-modal-message {
99+
white-space: pre-wrap;
100+
margin-bottom: 20px;
101+
}
102+
103+
/* Modal Schließen-Button */
104+
#details-modal-close {
105+
align-self: flex-end;
106+
padding: 6px 18px;
107+
font-size: 1em;
108+
}
109+
110+
/* Info-Button */
111+
.details-button {
112+
font-size: 0.8em;
113+
padding: 0 4px;
114+
margin-left: 6px;
115+
border-radius: 50%;
116+
}
117+
118+
/* Modal Header */
119+
#details-modal-header {
120+
margin-top: 0;
121+
margin-bottom: 16px;
122+
}

web/maintenance/systeminfo.html

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ <h1>Systeminformationen</h1>
1111
<p>Lade Daten...</p>
1212
</div>
1313
<div id="error"></div>
14+
<div id="details-modal" class="details-modal">
15+
<div class="details-modal-content">
16+
<h2 id="details-modal-header">Details</h2>
17+
<pre id="details-modal-message"></pre>
18+
<button id="details-modal-close">Schließen</button>
19+
</div>
20+
</div>
1421
<script>
1522
const fetchInterval = 5000; // 5 Sekunden
1623
const maxHistoryLength = 60; // z.B. 5 Minuten bei 5s Intervall
@@ -94,6 +101,16 @@ <h1>Systeminformationen</h1>
94101
for (const subKey in value) {
95102
if (Object.hasOwn(value, subKey)) {
96103
const v = value[subKey];
104+
html += `<tr><th>${subKey}`;
105+
// Falls "details" vorhanden, einen runden Info-Button anzeigen
106+
if (v && typeof v === "object" && "details" in v) {
107+
const infoBtnId = `info_${key}_${subKey}`.replace(
108+
/\W/g,
109+
"_"
110+
);
111+
html += ` <button class="details-button" data-details="${v.details}">i</button>`;
112+
}
113+
html += '</th><td style="text-align:right;">';
97114
if (
98115
v &&
99116
typeof v === "object" &&
@@ -102,10 +119,11 @@ <h1>Systeminformationen</h1>
102119
) {
103120
let num = Number(v.value);
104121
let formatted = isFinite(num) ? num.toFixed(1) : v.value;
105-
html += `<tr><th>${subKey}</th><td style="text-align:right;">${formatted} <span style="color:#888;font-size:0.95em">${v.unit}</span></td></tr>`;
122+
html += `${formatted} <span style="color:#888;font-size:0.95em">${v.unit}</span>`;
106123
} else {
107-
html += `<tr><th>${subKey}</th><td style="text-align:right;">${v}</td></tr>`;
124+
html += `${v}`;
108125
}
126+
html += "</td></tr>";
109127
}
110128
}
111129
html += "</table>";
@@ -168,6 +186,20 @@ <h1>Systeminformationen</h1>
168186
}
169187
}
170188
}
189+
190+
// Event-Handler für Info-Buttons (Details)
191+
document.querySelectorAll(".details-button").forEach((btn) => {
192+
btn.onclick = function () {
193+
const modal = document.getElementById("details-modal");
194+
const msg = document.getElementById("details-modal-message");
195+
msg.textContent = btn.getAttribute("data-details");
196+
const header = document.getElementById("details-modal-header");
197+
const th = btn.closest("th");
198+
let subKeyText = th ? th.childNodes[0].textContent.trim() : "";
199+
header.textContent = `Details zu '${subKeyText}'`;
200+
modal.style.display = "flex";
201+
};
202+
});
171203
}
172204

173205
function renderCharts() {
@@ -193,7 +225,8 @@ <h1>Systeminformationen</h1>
193225
let chartsHtml = '<div class="card-container">';
194226
for (const key in history) {
195227
if (!Object.hasOwn(history, key)) continue;
196-
if (!chartSections.some(section => key.startsWith(section))) continue;
228+
if (!chartSections.some((section) => key.startsWith(section)))
229+
continue;
197230
const value = history[key];
198231
// Prüfe, ob es sich um mehrere Reihen handelt (Objekt mit value/unit) oder Array
199232
if (Array.isArray(value)) {
@@ -248,7 +281,8 @@ <h2>${key}</h2>
248281
// Diagramme zeichnen
249282
for (const key in history) {
250283
if (!Object.hasOwn(history, key)) continue;
251-
if (!chartSections.some(section => key.startsWith(section))) continue;
284+
if (!chartSections.some((section) => key.startsWith(section)))
285+
continue;
252286
const value = history[key];
253287
if (Array.isArray(value)) {
254288
const canvas = document.getElementById(`chart_${key}`);
@@ -390,6 +424,13 @@ <h2>${key}</h2>
390424
}
391425
}
392426

427+
document.getElementById("details-modal-close").onclick = function () {
428+
document.getElementById("details-modal").style.display = "none";
429+
};
430+
document.getElementById("details-modal").onclick = function (e) {
431+
if (e.target === this) this.style.display = "none";
432+
};
433+
393434
fetchSystemInfo();
394435
setInterval(fetchSystemInfo, fetchInterval);
395436
</script>

web/maintenance/systeminfo_api.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ function getServiceStatus($services)
315315
function getTopProcesses($order, $limit)
316316
{
317317
// ps gibt: PID, Benutzer, CPU-Auslastung, Speicher, Befehl
318-
$data = ['comm', 'pid', '%cpu', '%mem'];
318+
$data = ['comm', 'pid', '%cpu', '%mem', 'command'];
319319
$index = array_search($order, $data);
320320
if ($index === false) {
321321
return [];
@@ -329,10 +329,11 @@ function getTopProcesses($order, $limit)
329329
for ($i = 1; $i < count($output); $i++) {
330330
// Spalten trennen (mehrere Leerzeichen)
331331
$cols = preg_split('/\s+/', trim($output[$i]), 5);
332-
if (count($cols) === 4) {
332+
if (count($cols) === 5) {
333333
$result[$cols[0] . ' (' . $cols[1] . ')'] = [
334334
'value' => (float)$cols[$index],
335-
'unit' => '%'
335+
'unit' => '%',
336+
'details' => $cols[4]
336337
];
337338
}
338339
}

0 commit comments

Comments
 (0)