""" Worker Pool Metriken-Dialog. Zeigt Performance- und Ressourcenverbrauch-Metriken für Saxon- und FOP-Worker-Pools an. """ import logging from PySide6.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, QPushButton, QTabWidget, QWidget, ) logger = logging.getLogger(__name__) class WorkerPoolMetricsDialog(QDialog): """ Dialog zur Anzeige von Worker-Pool-Metriken. """ def __init__(self, parent=None): """ Initialisiert den Metriken-Dialog. Args: parent: Eltern-Widget """ super().__init__(parent) self.setWindowTitle("Worker Pool Performance-Metriken") self.resize(800, 600) self._setup_ui() self._load_metrics() def _setup_ui(self): """Erstellt die UI-Elemente.""" layout = QVBoxLayout(self) # Tab-Widget für Saxon und FOP self.tab_widget = QTabWidget() layout.addWidget(self.tab_widget) # Saxon-Tab self.saxon_tab = self._create_metrics_tab("Saxon Worker Pool") self.tab_widget.addTab(self.saxon_tab, "Saxon (XSLT)") # FOP-Tab self.fop_tab = self._create_metrics_tab("FOP Worker Pool") self.tab_widget.addTab(self.fop_tab, "FOP (PDF)") # Schließen-Button button_layout = QHBoxLayout() button_layout.addStretch() close_button = QPushButton("Schließen") close_button.clicked.connect(self.accept) button_layout.addWidget(close_button) layout.addLayout(button_layout) def _create_metrics_tab(self, title: str) -> QWidget: """ Erstellt ein Tab-Widget für Metriken. Args: title: Titel der Metrik-Gruppe Returns: QWidget mit Metriken """ tab = QWidget() layout = QVBoxLayout(tab) # Status-Label status_label = QLabel("Status: Nicht initialisiert") status_label.setObjectName("status_label") layout.addWidget(status_label) # Kompilierungs-Metriken compile_group = QGroupBox("Kompilierung") compile_layout = QVBoxLayout(compile_group) compile_time_label = QLabel("Kompilierungszeit: -") compile_time_label.setObjectName("compile_time_label") compile_layout.addWidget(compile_time_label) layout.addWidget(compile_group) # Worker-Start-Metriken worker_start_group = QGroupBox("Worker-Start") worker_start_layout = QVBoxLayout(worker_start_group) worker_count_label = QLabel("Anzahl Worker: -") worker_count_label.setObjectName("worker_count_label") worker_start_layout.addWidget(worker_count_label) total_start_time_label = QLabel("Summe Startzeit: -") total_start_time_label.setObjectName("total_start_time_label") worker_start_layout.addWidget(total_start_time_label) avg_start_time_label = QLabel("Durchschnitt Startzeit: -") avg_start_time_label.setObjectName("avg_start_time_label") worker_start_layout.addWidget(avg_start_time_label) layout.addWidget(worker_start_group) # RAM-Metriken ram_group = QGroupBox("Arbeitsspeicher (RAM)") ram_layout = QVBoxLayout(ram_group) ram_before_label = QLabel("RAM vor Transformation: -") ram_before_label.setObjectName("ram_before_label") ram_layout.addWidget(ram_before_label) ram_before_avg_label = QLabel("RAM vor Transformation (Durchschnitt/Worker): -") ram_before_avg_label.setObjectName("ram_before_avg_label") ram_layout.addWidget(ram_before_avg_label) ram_after_label = QLabel("RAM nach Transformation: -") ram_after_label.setObjectName("ram_after_label") ram_layout.addWidget(ram_after_label) ram_after_avg_label = QLabel("RAM nach Transformation (Durchschnitt/Worker): -") ram_after_avg_label.setObjectName("ram_after_avg_label") ram_layout.addWidget(ram_after_avg_label) ram_delta_label = QLabel("RAM-Zunahme: -") ram_delta_label.setObjectName("ram_delta_label") ram_layout.addWidget(ram_delta_label) layout.addWidget(ram_group) layout.addStretch() return tab def _load_metrics(self): """Lädt und zeigt die Metriken an.""" # Hole MainWindow-Instanz (parent) main_window = self.parent() # Saxon Worker Pool - verwende gespeicherte Metriken if hasattr(main_window, "last_saxon_metrics") and main_window.last_saxon_metrics: self._update_metrics_tab_from_metrics( self.saxon_tab, main_window.last_saxon_metrics, "Saxon Worker Pool" ) else: self._set_tab_status( self.saxon_tab, "Keine Metriken verfügbar - bitte erst eine Transformation durchführen" ) # FOP Worker Pool - verwende gespeicherte Metriken if hasattr(main_window, "last_fop_metrics") and main_window.last_fop_metrics: self._update_metrics_tab_from_metrics(self.fop_tab, main_window.last_fop_metrics, "FOP Worker Pool") else: self._set_tab_status( self.fop_tab, "Keine Metriken verfügbar - bitte erst eine Transformation durchführen" ) def _set_tab_status(self, tab: QWidget, status: str): """ Setzt den Status-Text eines Tabs. Args: tab: Das Tab-Widget status: Der Status-Text """ status_label = tab.findChild(QLabel, "status_label") if status_label: status_label.setText(f"Status: {status}") def _update_metrics_tab_from_metrics(self, tab: QWidget, metrics, pool_name: str): """ Aktualisiert die Metriken in einem Tab (direkt aus Metriken-Objekt). Args: tab: Das Tab-Widget metrics: Das WorkerPoolMetrics-Objekt pool_name: Name des Pools """ # Status - berechne Worker-Anzahl aus Metriken num_workers = len(metrics.worker_start_times) if metrics.worker_start_times else 0 self._set_tab_status(tab, f"Letzte Transformation ({num_workers} Worker)") # Kompilierung compile_time_label = tab.findChild(QLabel, "compile_time_label") if compile_time_label: compile_time_label.setText(f"Kompilierungszeit: {metrics.compilation_time_seconds:.3f} s") # Worker-Start worker_count_label = tab.findChild(QLabel, "worker_count_label") if worker_count_label: worker_count_label.setText(f"Anzahl Worker: {len(metrics.worker_start_times)}") total_start_time_label = tab.findChild(QLabel, "total_start_time_label") if total_start_time_label: total_start_time_label.setText( f"Summe Startzeit: {metrics.total_worker_start_time_seconds:.3f} s" ) avg_start_time_label = tab.findChild(QLabel, "avg_start_time_label") if avg_start_time_label: avg_start_time_label.setText( f"Durchschnitt Startzeit: {metrics.average_worker_start_time_seconds:.3f} s/Worker" ) # RAM ram_before_label = tab.findChild(QLabel, "ram_before_label") if ram_before_label: if metrics.total_ram_before_mb > 0: ram_before_label.setText(f"RAM vor Transformation: {metrics.total_ram_before_mb:.1f} MB") else: ram_before_label.setText("RAM vor Transformation: Noch nicht gemessen") ram_before_avg_label = tab.findChild(QLabel, "ram_before_avg_label") if ram_before_avg_label: if metrics.average_ram_before_mb > 0: ram_before_avg_label.setText( f"RAM vor Transformation (Durchschnitt/Worker): {metrics.average_ram_before_mb:.1f} MB" ) else: ram_before_avg_label.setText( "RAM vor Transformation (Durchschnitt/Worker): Noch nicht gemessen" ) ram_after_label = tab.findChild(QLabel, "ram_after_label") if ram_after_label: if metrics.total_ram_after_mb > 0: ram_after_label.setText(f"RAM nach Transformation: {metrics.total_ram_after_mb:.1f} MB") else: ram_after_label.setText("RAM nach Transformation: Noch nicht gemessen") ram_after_avg_label = tab.findChild(QLabel, "ram_after_avg_label") if ram_after_avg_label: if metrics.average_ram_after_mb > 0: ram_after_avg_label.setText( f"RAM nach Transformation (Durchschnitt/Worker): {metrics.average_ram_after_mb:.1f} MB" ) else: ram_after_avg_label.setText( "RAM nach Transformation (Durchschnitt/Worker): Noch nicht gemessen" ) ram_delta_label = tab.findChild(QLabel, "ram_delta_label") if ram_delta_label: if metrics.total_ram_before_mb > 0 and metrics.total_ram_after_mb > 0: delta = metrics.total_ram_after_mb - metrics.total_ram_before_mb delta_percent = (delta / metrics.total_ram_before_mb * 100) if metrics.total_ram_before_mb > 0 else 0 ram_delta_label.setText(f"RAM-Zunahme: {delta:.1f} MB ({delta_percent:+.1f}%)") else: ram_delta_label.setText("RAM-Zunahme: Noch nicht gemessen")