/* * Debug-Charts.js * JavaScript-Funktionen für das Rendering von Diagrammen und Visualisierungen * im MYP Debug-Server. */ // Globale Variablen für Charts let cpuUsageChart = null; let memoryUsageChart = null; let networkTrafficChart = null; let diskUsageChart = null; let containerStatusChart = null; // Hilfsfunktion zum Formatieren von Bytes function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } // Aktualisiere Systemdiagramme function updateSystemCharts() { fetch('/api/system/metrics') .then(response => response.json()) .then(data => { // CPU-Nutzung aktualisieren if (cpuUsageChart) { cpuUsageChart.data.labels.push(new Date().toLocaleTimeString()); cpuUsageChart.data.datasets[0].data.push(data.cpu_percent); // Behalte nur die letzten 30 Datenpunkte if (cpuUsageChart.data.labels.length > 30) { cpuUsageChart.data.labels.shift(); cpuUsageChart.data.datasets[0].data.shift(); } cpuUsageChart.update(); } // Speichernutzung aktualisieren if (memoryUsageChart) { memoryUsageChart.data.datasets[0].data = [ data.memory.used, data.memory.available ]; memoryUsageChart.update(); // Aktualisiere die Speicherinfo-Texte document.getElementById('memory-used').textContent = formatBytes(data.memory.used); document.getElementById('memory-available').textContent = formatBytes(data.memory.available); document.getElementById('memory-total').textContent = formatBytes(data.memory.total); } // Festplattennutzung aktualisieren if (diskUsageChart && data.disk_usage) { const diskLabels = []; const diskUsed = []; const diskFree = []; for (const disk of data.disk_usage) { diskLabels.push(disk.mountpoint); diskUsed.push(disk.used); diskFree.push(disk.free); } diskUsageChart.data.labels = diskLabels; diskUsageChart.data.datasets[0].data = diskUsed; diskUsageChart.data.datasets[1].data = diskFree; diskUsageChart.update(); } }) .catch(error => console.error('Fehler beim Abrufen der Systemmetriken:', error)); } // Initialisiere CPU-Nutzungsdiagramm function initCpuUsageChart() { const ctx = document.getElementById('cpu-usage-chart').getContext('2d'); cpuUsageChart = new Chart(ctx, { type: 'line', data: { labels: [], datasets: [{ label: 'CPU-Auslastung (%)', data: [], borderColor: 'rgb(75, 192, 192)', tension: 0.1, fill: true, backgroundColor: 'rgba(75, 192, 192, 0.2)' }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, max: 100, title: { display: true, text: 'Auslastung (%)' } }, x: { title: { display: true, text: 'Zeit' } } }, plugins: { title: { display: true, text: 'CPU-Auslastung', font: { size: 16 } } } } }); } // Initialisiere Speichernutzungsdiagramm function initMemoryUsageChart() { const ctx = document.getElementById('memory-usage-chart').getContext('2d'); memoryUsageChart = new Chart(ctx, { type: 'doughnut', data: { labels: ['Verwendet', 'Verfügbar'], datasets: [{ data: [0, 0], backgroundColor: [ 'rgba(255, 99, 132, 0.7)', 'rgba(75, 192, 192, 0.7)' ] }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { title: { display: true, text: 'Speichernutzung', font: { size: 16 } } } } }); } // Initialisiere Festplattennutzungsdiagramm function initDiskUsageChart() { const ctx = document.getElementById('disk-usage-chart').getContext('2d'); diskUsageChart = new Chart(ctx, { type: 'bar', data: { labels: [], datasets: [ { label: 'Belegt', data: [], backgroundColor: 'rgba(255, 99, 132, 0.7)' }, { label: 'Frei', data: [], backgroundColor: 'rgba(75, 192, 192, 0.7)' } ] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { stacked: true, title: { display: true, text: 'Laufwerk' } }, y: { stacked: true, title: { display: true, text: 'Speicherplatz (Bytes)' }, ticks: { callback: function(value) { return formatBytes(value); } } } }, plugins: { title: { display: true, text: 'Festplattennutzung', font: { size: 16 } } } } }); } // Aktualisiere Docker-Container-Status function updateContainerStatus() { fetch('/api/docker/status') .then(response => response.json()) .then(data => { const containerTable = document.getElementById('container-table'); if (!containerTable) return; // Tabelle leeren containerTable.innerHTML = ''; // Überschriftenzeile const headerRow = document.createElement('tr'); ['Name', 'Status', 'CPU', 'Speicher', 'Netzwerk', 'Aktionen'].forEach(header => { const th = document.createElement('th'); th.textContent = header; headerRow.appendChild(th); }); containerTable.appendChild(headerRow); // Containerdaten data.containers.forEach(container => { const row = document.createElement('tr'); // Name const nameCell = document.createElement('td'); nameCell.textContent = container.name; row.appendChild(nameCell); // Status const statusCell = document.createElement('td'); const statusBadge = document.createElement('span'); statusBadge.textContent = container.status; statusBadge.className = container.running ? 'status-badge running' : 'status-badge stopped'; statusCell.appendChild(statusBadge); row.appendChild(statusCell); // CPU const cpuCell = document.createElement('td'); cpuCell.textContent = container.cpu_percent ? `${container.cpu_percent.toFixed(2)}%` : 'N/A'; row.appendChild(cpuCell); // Speicher const memoryCell = document.createElement('td'); memoryCell.textContent = container.memory_usage ? formatBytes(container.memory_usage) : 'N/A'; row.appendChild(memoryCell); // Netzwerk const networkCell = document.createElement('td'); if (container.network_io) { networkCell.innerHTML = `↓ ${formatBytes(container.network_io.rx_bytes)}
↑ ${formatBytes(container.network_io.tx_bytes)}`; } else { networkCell.textContent = 'N/A'; } row.appendChild(networkCell); // Aktionen const actionsCell = document.createElement('td'); const actionsDiv = document.createElement('div'); actionsDiv.className = 'container-actions'; // Restart-Button const restartBtn = document.createElement('button'); restartBtn.className = 'btn btn-warning btn-sm'; restartBtn.innerHTML = ''; restartBtn.title = 'Container neustarten'; restartBtn.onclick = () => restartContainer(container.id); actionsDiv.appendChild(restartBtn); // Logs-Button const logsBtn = document.createElement('button'); logsBtn.className = 'btn btn-info btn-sm'; logsBtn.innerHTML = ''; logsBtn.title = 'Container-Logs anzeigen'; logsBtn.onclick = () => showContainerLogs(container.id); actionsDiv.appendChild(logsBtn); actionsCell.appendChild(actionsDiv); row.appendChild(actionsCell); containerTable.appendChild(row); }); // Container-Status-Diagramm aktualisieren updateContainerStatusChart(data.containers); }) .catch(error => console.error('Fehler beim Abrufen der Docker-Informationen:', error)); } // Initialisiere Container-Status-Diagramm function initContainerStatusChart() { const ctx = document.getElementById('container-status-chart').getContext('2d'); containerStatusChart = new Chart(ctx, { type: 'pie', data: { labels: ['Aktiv', 'Inaktiv'], datasets: [{ data: [0, 0], backgroundColor: [ 'rgba(75, 192, 192, 0.7)', 'rgba(255, 99, 132, 0.7)' ] }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { title: { display: true, text: 'Container-Status', font: { size: 16 } } } } }); } // Aktualisiere Container-Status-Diagramm function updateContainerStatusChart(containers) { if (!containerStatusChart) return; const running = containers.filter(c => c.running).length; const stopped = containers.filter(c => !c.running).length; containerStatusChart.data.datasets[0].data = [running, stopped]; containerStatusChart.update(); } // Container neustarten function restartContainer(containerId) { fetch(`/api/docker/restart/${containerId}`, { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.success) { showMessage('Container wird neugestartet...', false); // Nach kurzer Verzögerung aktualisieren setTimeout(updateContainerStatus, 2000); } else { showMessage('Fehler beim Neustarten des Containers: ' + data.message, true); } }) .catch(error => { showMessage('Fehler beim Neustarten des Containers', true); console.error('Fehler beim Neustarten des Containers:', error); }); } // Container-Logs anzeigen function showContainerLogs(containerId) { fetch(`/api/docker/logs/${containerId}`) .then(response => response.json()) .then(data => { if (data.logs) { // Modal erstellen und anzeigen const modal = document.createElement('div'); modal.className = 'modal'; modal.innerHTML = ` `; document.body.appendChild(modal); // Modal schließen, wenn auf X geklickt wird modal.querySelector('.close').onclick = function() { document.body.removeChild(modal); }; // Modal schließen, wenn außerhalb geklickt wird window.onclick = function(event) { if (event.target === modal) { document.body.removeChild(modal); } }; // Modal anzeigen modal.style.display = 'block'; } else { showMessage('Keine Logs verfügbar', true); } }) .catch(error => { showMessage('Fehler beim Abrufen der Container-Logs', true); console.error('Fehler beim Abrufen der Container-Logs:', error); }); } // Zeige Fehlermeldung oder Erfolgsmeldung function showMessage(message, isError = false) { const messageEl = document.getElementById('message'); if (messageEl) { messageEl.textContent = message; messageEl.className = isError ? 'message message-error' : 'message message-success'; messageEl.style.display = 'block'; // Verstecke Nachricht nach 5 Sekunden setTimeout(() => { messageEl.style.display = 'none'; }, 5000); } } // Initialisiere alle Diagramme function initAllCharts() { // Überprüfe, ob Chart.js geladen ist if (typeof Chart !== 'undefined') { if (document.getElementById('cpu-usage-chart')) { initCpuUsageChart(); } if (document.getElementById('memory-usage-chart')) { initMemoryUsageChart(); } if (document.getElementById('disk-usage-chart')) { initDiskUsageChart(); } if (document.getElementById('container-status-chart')) { initContainerStatusChart(); } // Initialen Datenabruf starten updateSystemCharts(); updateContainerStatus(); // Regelmäßige Aktualisierung der Diagramme setInterval(updateSystemCharts, 5000); // Alle 5 Sekunden aktualisieren setInterval(updateContainerStatus, 10000); // Alle 10 Sekunden aktualisieren } else { console.error('Chart.js konnte nicht geladen werden.'); } } // Automatischer Start beim Laden der Seite document.addEventListener('DOMContentLoaded', function() { initAllCharts(); });