improved logging
This commit is contained in:
@@ -256,6 +256,12 @@ class AppWindowLiveProcessingMixin:
|
||||
for name, value in fields.items()
|
||||
if name not in {"history_command", "history_command_seq"}
|
||||
}
|
||||
# Log only field names (not values) so remote edits are traceable
|
||||
# without recording arbitrary client-supplied payloads.
|
||||
self._log_debug(
|
||||
f"Applying web live settings: fields={sorted(settings)}, "
|
||||
f"history_command={history_command}."
|
||||
)
|
||||
self._suppress_live_settings_handler = True
|
||||
try:
|
||||
# processor_mode first: dual-sourced gpr_* fields route to the gpr or
|
||||
|
||||
@@ -218,7 +218,16 @@ class AppWindowConfigProfileIOMixin:
|
||||
self._show_exception("Failed to load config profile", exc)
|
||||
|
||||
def _apply_loaded_profile(self, profile: GuiProfileModel, profile_path: Path) -> None:
|
||||
"""Apply already parsed profile to GUI state without restarting the pipeline."""
|
||||
"""Apply an already parsed profile to GUI state without restarting the pipeline.
|
||||
|
||||
Repopulates every radar/processing/preprocess widget under signal blockers,
|
||||
resizes history buffers, and refreshes derived state. The pipeline is left
|
||||
untouched; callers handle user-facing logging and error reporting.
|
||||
"""
|
||||
self._log_debug(
|
||||
f"Applying loaded profile: path={profile_path}, "
|
||||
f"has_gui_state={profile.gui is not None}."
|
||||
)
|
||||
config = profile.run_config.clone()
|
||||
gui_state = profile.gui if profile.gui is not None else self._default_gui_state_for_config(config)
|
||||
self._defaults_config = config
|
||||
|
||||
@@ -422,6 +422,7 @@ class AppWindowConfigStateBuildersMixin:
|
||||
|
||||
config.runtime.settling_ms = int(self._settling_ms.text().strip())
|
||||
config.runtime.processing_live_config_path = str(self._live_config_writer.path)
|
||||
config.logging.level = self._log_level_combo.currentText().strip().lower()
|
||||
|
||||
if config.is_matrix_radar:
|
||||
if config.is_multi_device and len(config.radar.multi_device.slave_serials) != 2:
|
||||
|
||||
@@ -304,16 +304,22 @@ class AppWindowPipelineMixin:
|
||||
self._log("All pipeline processes stopped")
|
||||
|
||||
def _close_readers(self, *, keep_results: bool = False) -> None:
|
||||
"""Close active ring readers."""
|
||||
"""Close active ring readers; keep the results reader when ``keep_results``."""
|
||||
closed = []
|
||||
if self._raw_reader is not None:
|
||||
self._raw_reader.close()
|
||||
self._raw_reader = None
|
||||
closed.append("raw")
|
||||
if self._pre_reader is not None:
|
||||
self._pre_reader.close()
|
||||
self._pre_reader = None
|
||||
closed.append("preprocessed")
|
||||
if not keep_results and self._result_reader is not None:
|
||||
self._result_reader.close()
|
||||
self._result_reader = None
|
||||
closed.append("results")
|
||||
if closed:
|
||||
self._log_debug(f"Closed ring readers: {', '.join(closed)}.")
|
||||
|
||||
def _poll_rings(self) -> None:
|
||||
"""Poll readers, ingest history, and trigger rendering."""
|
||||
|
||||
@@ -58,7 +58,13 @@ class AppWindowPreprocessMixin:
|
||||
"""Clear selected preprocess sets when radar-key-defining settings change."""
|
||||
try:
|
||||
radar_key = self._radar_key_from_ui()
|
||||
except Exception:
|
||||
except Exception as exc: # noqa: BLE001
|
||||
# Radar fields can be mid-edit (empty/partial) while signals fire; the
|
||||
# key cannot be computed yet, so skip until the inputs are valid again.
|
||||
self._log_debug(
|
||||
f"Skipping preprocess-selection reset; radar key unavailable: "
|
||||
f"{type(exc).__name__}: {exc}"
|
||||
)
|
||||
return
|
||||
|
||||
previous_radar_key = getattr(self, "_selected_preprocess_radar_key", radar_key)
|
||||
@@ -778,8 +784,11 @@ class AppWindowPreprocessMixin:
|
||||
)
|
||||
|
||||
def _cleanup_capture_session(self) -> None:
|
||||
"""Close and clear current capture session object."""
|
||||
"""Close and clear the current capture session object."""
|
||||
if self._capture_session is not None:
|
||||
self._log_debug(
|
||||
f"Closing capture session: kind={self._capture_session.kind}."
|
||||
)
|
||||
self._capture_session.close()
|
||||
self._capture_session = None
|
||||
self._update_capture_dialog_state()
|
||||
|
||||
@@ -33,6 +33,7 @@ from python_app.gui.controllers.sections import (
|
||||
build_radar_group,
|
||||
build_switch_group,
|
||||
)
|
||||
from python_app.logging_setup import LOG_LEVELS
|
||||
|
||||
|
||||
class AppWindowUiMixin:
|
||||
@@ -178,6 +179,20 @@ class AppWindowUiMixin:
|
||||
self._log_toggle_button.setObjectName("sectionToggleButton")
|
||||
self._log_toggle_button.clicked.connect(lambda: self._toggle_log_panel())
|
||||
|
||||
# Log-level selector: live verbosity control, persisted to run_config.
|
||||
self._log_level_label = QLabel("Level", self._settings_panel)
|
||||
self._log_level_label.setObjectName("hintLabel")
|
||||
self._log_level_combo = QComboBox(self._settings_panel)
|
||||
self._log_level_combo.setObjectName("logLevelCombo")
|
||||
self._log_level_combo.addItems([name.capitalize() for name in LOG_LEVELS])
|
||||
self._log_level_combo.setToolTip("Logging verbosity — applied live and saved to run_config")
|
||||
current_level = self._defaults_config.logging.level.capitalize()
|
||||
current_index = self._log_level_combo.findText(current_level)
|
||||
if current_index >= 0:
|
||||
self._log_level_combo.setCurrentIndex(current_index)
|
||||
# Connect AFTER seeding the value so reflecting the config does not save it back.
|
||||
self._log_level_combo.currentTextChanged.connect(self._on_log_level_selected)
|
||||
|
||||
self._log_box = QTextEdit(self._settings_panel)
|
||||
self._log_box.setObjectName("runtimeLogBox")
|
||||
self._log_box.setReadOnly(True)
|
||||
@@ -196,6 +211,8 @@ class AppWindowUiMixin:
|
||||
header_layout.setSpacing(8)
|
||||
header_layout.addWidget(self._log_panel_title)
|
||||
header_layout.addStretch(1)
|
||||
header_layout.addWidget(self._log_level_label)
|
||||
header_layout.addWidget(self._log_level_combo)
|
||||
header_layout.addWidget(self._log_toggle_button)
|
||||
|
||||
panel_layout.addWidget(header_row)
|
||||
|
||||
@@ -198,6 +198,7 @@ class AppWindowWebMixin:
|
||||
with contextlib.suppress(Exception):
|
||||
server.stop()
|
||||
self._web_server = None
|
||||
self._log("Web UI stopped.")
|
||||
self._web_controller = None
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user