2026-01-06 20:58:37 +01:00
|
|
|
"""
|
|
|
|
|
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: <i>Nicht initialisiert</i>")
|
|
|
|
|
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."""
|
2026-01-07 19:00:35 +01:00
|
|
|
# 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"
|
|
|
|
|
)
|
2026-01-06 20:58:37 +01:00
|
|
|
else:
|
2026-01-07 19:00:35 +01:00
|
|
|
self._set_tab_status(
|
|
|
|
|
self.saxon_tab, "<i>Keine Metriken verfügbar - bitte erst eine Transformation durchführen</i>"
|
|
|
|
|
)
|
2026-01-06 20:58:37 +01:00
|
|
|
|
2026-01-07 19:00:35 +01:00
|
|
|
# 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")
|
2026-01-06 20:58:37 +01:00
|
|
|
else:
|
2026-01-07 19:00:35 +01:00
|
|
|
self._set_tab_status(
|
|
|
|
|
self.fop_tab, "<i>Keine Metriken verfügbar - bitte erst eine Transformation durchführen</i>"
|
|
|
|
|
)
|
2026-01-06 20:58:37 +01:00
|
|
|
|
|
|
|
|
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}")
|
|
|
|
|
|
2026-01-07 19:00:35 +01:00
|
|
|
def _update_metrics_tab_from_metrics(self, tab: QWidget, metrics, pool_name: str):
|
2026-01-06 20:58:37 +01:00
|
|
|
"""
|
2026-01-07 19:00:35 +01:00
|
|
|
Aktualisiert die Metriken in einem Tab (direkt aus Metriken-Objekt).
|
2026-01-06 20:58:37 +01:00
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
tab: Das Tab-Widget
|
2026-01-07 19:00:35 +01:00
|
|
|
metrics: Das WorkerPoolMetrics-Objekt
|
2026-01-06 20:58:37 +01:00
|
|
|
pool_name: Name des Pools
|
|
|
|
|
"""
|
2026-01-07 19:00:35 +01:00
|
|
|
# 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"<b>Letzte Transformation</b> ({num_workers} Worker)")
|
2026-01-06 20:58:37 +01:00
|
|
|
|
|
|
|
|
# Kompilierung
|
|
|
|
|
compile_time_label = tab.findChild(QLabel, "compile_time_label")
|
|
|
|
|
if compile_time_label:
|
|
|
|
|
compile_time_label.setText(f"Kompilierungszeit: <b>{metrics.compilation_time_seconds:.3f} s</b>")
|
|
|
|
|
|
|
|
|
|
# Worker-Start
|
|
|
|
|
worker_count_label = tab.findChild(QLabel, "worker_count_label")
|
|
|
|
|
if worker_count_label:
|
|
|
|
|
worker_count_label.setText(f"Anzahl Worker: <b>{len(metrics.worker_start_times)}</b>")
|
|
|
|
|
|
|
|
|
|
total_start_time_label = tab.findChild(QLabel, "total_start_time_label")
|
|
|
|
|
if total_start_time_label:
|
|
|
|
|
total_start_time_label.setText(
|
|
|
|
|
f"Summe Startzeit: <b>{metrics.total_worker_start_time_seconds:.3f} s</b>"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
avg_start_time_label = tab.findChild(QLabel, "avg_start_time_label")
|
|
|
|
|
if avg_start_time_label:
|
|
|
|
|
avg_start_time_label.setText(
|
|
|
|
|
f"Durchschnitt Startzeit: <b>{metrics.average_worker_start_time_seconds:.3f} s/Worker</b>"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 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: <b>{metrics.total_ram_before_mb:.1f} MB</b>")
|
|
|
|
|
else:
|
|
|
|
|
ram_before_label.setText("RAM vor Transformation: <i>Noch nicht gemessen</i>")
|
|
|
|
|
|
|
|
|
|
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): <b>{metrics.average_ram_before_mb:.1f} MB</b>"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
ram_before_avg_label.setText(
|
|
|
|
|
"RAM vor Transformation (Durchschnitt/Worker): <i>Noch nicht gemessen</i>"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
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: <b>{metrics.total_ram_after_mb:.1f} MB</b>")
|
|
|
|
|
else:
|
|
|
|
|
ram_after_label.setText("RAM nach Transformation: <i>Noch nicht gemessen</i>")
|
|
|
|
|
|
|
|
|
|
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): <b>{metrics.average_ram_after_mb:.1f} MB</b>"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
ram_after_avg_label.setText(
|
|
|
|
|
"RAM nach Transformation (Durchschnitt/Worker): <i>Noch nicht gemessen</i>"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
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: <b>{delta:.1f} MB ({delta_percent:+.1f}%)</b>")
|
|
|
|
|
else:
|
|
|
|
|
ram_delta_label.setText("RAM-Zunahme: <i>Noch nicht gemessen</i>")
|