Skip to content

GUI: Add "Generate debug log" action - #3328

Merged
C-Achard merged 20 commits into
mainfrom
cy/debug-logger-ui
May 18, 2026
Merged

GUI: Add "Generate debug log" action#3328
C-Achard merged 20 commits into
mainfrom
cy/debug-logger-ui

Conversation

@C-Achard

Copy link
Copy Markdown
Collaborator

Motivation

To standardize error reports and make it easier for users to share diagnostics, this PR adds a utility that generates a copy-pasteable summary of the user environment.

This is added here with three components:

  • A logging recorder, which is deeplabcut-scoped
  • A timing decorator to help identify speed bottlenecks
  • A new GUI menu (Help > Generate debug log) that provides users with an issue-ready summary of their env

Scope

The initial version added here provides:

Debug utils

  • Recent application logs via logging
  • Python / OS information
  • Installed package versions,
    • With GUI and optional TensorFlow details
  • External tool availability such as ffmpeg

GUI

  • New debug log action

Tests

  • Logger has a minimal test suite
  • GUI tests will have to be added in the future

Note

No project or config info is included as of yet. This could be a very worthwhile extension in subsquent PRs.


Automated summary

This pull request introduces a new debug logging and reporting system for DeepLabCut, including both core functionality and GUI integration. The changes provide a robust mechanism to capture, view, and report diagnostic information, making it easier for users and developers to troubleshoot issues. The update also adds comprehensive tests for the debug recorder and integrates a new "Generate debug log" action into the application's Help menu.

Core debug logging and reporting system:

  • Added a new deeplabcut.core.debug package that exposes debug logging utilities and report generation functions, including InMemoryDebugRecorder, build_debug_report, and related helpers via its __init__.py.
  • Implemented _debug_utils.py with helper functions to resolve executable paths and versions, supporting richer debug reports.

GUI integration:

  • Introduced debug_dialog.py, a new GUI dialog for displaying and copying debug logs and reports, with utilities to create actions and dialogs for generating debug logs.
  • Updated gui/dialogs/__init__.py to export the new debug dialog utilities.
  • Integrated the debug recorder into the main application window (window.py), initializing it on startup and adding a "Generate debug log" action to the Help menu for easy access. [1] [2] [3] [4]

Testing:

  • Added a comprehensive test suite (test_logger.py) covering recorder installation, message capture, bounded queue behavior, text rendering, clearing, and log timing utilities.

C-Achard added 4 commits May 12, 2026 16:14
Introduce a new debug subsystem under deeplabcut/core/debug. Adds an in-memory, bounded log recorder (InMemoryDebugRecorder) with safe fail-open semantics, helper functions to install/get the recorder, and a scoped log_timing context manager. Provides utilities to collect runtime, package, and external executable information (LibrarySpec, ExecutableSpec, collect_version_summary, collect_executable_summary, collect_debug_sections) and to format/assemble a full debug report (format_debug_report, build_debug_report). Includes small helper functions (_which, _command_version) and sane defaults (lists of core/GUI/TensorFlow libs, ffmpeg executable). Exports are wired in __init__.py.
Introduce a reusable debug text dialog and helper functions for generating and displaying DeepLabCut diagnostic reports. Adds deeplabcut/gui/dialogs/debug_dialog.py implementing DebugTextDialog (read-only log view with refresh/copy/keyboard shortcut), providers to render logs and full issue reports, show_debug_report_dialog to install/reuse recorders and present the report, and create_generate_debug_log_action to wire up a QAction. Also exports these symbols via deeplabcut/gui/dialogs/__init__.py. Dialog instances are attached to the parent to avoid GC and duplicate windows.
Import and install a debug recorder and add a "Generate Debug Log" action to the Help menu. The patch imports create_generate_debug_log_action and install_debug_recorder, creates a recorder (logger_name="deeplabcut"), builds the debug-log action with specified options (include_module_paths=False, include_executable_paths=True, log_limit=1000), inserts it into the Help menu with a separator, and adjusts menu sizing. This allows users to generate debug logs from the GUI.
Add a new test module for deeplabcut.core.debug covering InMemoryDebugRecorder and log_timing. Tests verify install_debug_recorder idempotency and retrieval, message and exception capture, bounded buffer behavior, render_text contents, clear() resetting records and drop count, and log_timing behavior when enabled, disabled, and with thresholding. Uses pytest fixtures to create isolated logger namespaces and monkeypatch to simulate timings and logger behavior.
@C-Achard
C-Achard requested a review from Copilot May 12, 2026 14:53
@C-Achard C-Achard self-assigned this May 12, 2026
@C-Achard C-Achard added enhancement New feature or request GUI issues relating to GUI labels May 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a DeepLabCut-scoped debug reporting utility (in-memory log recorder + environment/package/tool summary) and wires it into the GUI via a new Help → Generate debug log action that shows a copy/paste-ready report dialog.

Changes:

  • Added deeplabcut.core.debug utilities to record recent logs and build an environment/debug report.
  • Added a new GUI dialog + action factory to display/copy the generated debug report.
  • Added a minimal pytest suite covering the in-memory recorder and timing context manager.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
deeplabcut/core/debug/debug_logger.py Implements the recorder, timing helper, environment/tool/package collection, and report formatting.
deeplabcut/core/debug/_debug_utils.py Adds helper utilities for resolving executables and extracting version output.
deeplabcut/core/debug/__init__.py Exposes the debug utilities as a public package API.
deeplabcut/gui/dialogs/debug_dialog.py Adds a reusable dialog for viewing/copying debug text + helpers to open it from actions.
deeplabcut/gui/dialogs/__init__.py Exports the new debug dialog helpers at the package level.
deeplabcut/gui/window.py Installs the recorder at GUI startup and adds the Help menu action.
tests/core/debug/test_logger.py Adds tests for recorder behavior and log_timing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread deeplabcut/core/debug/debug_logger.py
Comment thread deeplabcut/core/debug/debug_logger.py Outdated
Comment thread deeplabcut/gui/window.py
Comment thread deeplabcut/gui/dialogs/debug_dialog.py
Comment thread deeplabcut/core/debug/__init__.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py
Comment thread deeplabcut/core/debug/_debug_utils.py
Comment thread deeplabcut/core/debug/__init__.py
Comment thread deeplabcut/gui/dialogs/__init__.py
C-Achard added 5 commits May 13, 2026 10:08
Causes conflicts with pytorch tests of same name in CI
Add project/license header comments to deeplabcut/core/debug/__init__.py and deeplabcut/gui/dialogs/__init__.py. In core/debug/__init__.py, clean up the public API exports: remove internal symbols DLC_LOG_TIMING and LOG_QUEUE_MAXLEN from __all__, reorder entries, and ensure collect_executable_summary is exported. These changes clarify public exports and add attribution/licensing headers.
Replace generic "GUI" and "console" loggers with namespaced loggers ("deeplabcut.gui" and "deeplabcut.gui.console"). Store a console logger on the MainWindow instance and use it for setting level and printing status messages. This standardizes logger names and avoids relying on a global "console" logger.
Add DebugTextDialog.update_content to update window title, text provider, and hint when reusing an existing dialog instance. Update _get_or_create_debug_dialog to call update_content for existing dialogs instead of recreating them. Rename the initial_hint parameter to text_hint and adjust the show_debug_report_dialog call site accordingly. This lets the debug dialog refresh its metadata without reconstructing the widget.
Add environment-driven debug/timing configuration and make the in-memory debug recorder less intrusive. Changes:
- deeplabcut/core/debug/_debug_utils.py: add license header, import os, add reload_debug_settings_from_env(), and helper parsers _env_flag and _env_optional_float to read boolean/optional-float env vars.
- deeplabcut/core/debug/debug_logger.py: add license header, read DLC_LOG_TIMING and DLC_LOG_TIMING_THRESHOLD_MS from environment, import the new env helpers, and use an effective_threshold in log_timing().
- install_debug_recorder(): add handler_level and ensure_logger_level params, use handler_level for the recorder, and only lower the logger level when explicitly requested.
- Adjust external tools section reporting logic to avoid misleading reporting when executables is None.

Rationale: allow debug timing and thresholds to be controlled via environment variables, make recorder installation configurable without forcing global logger verbosity, and improve robustness of external-tool reporting.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment thread deeplabcut/core/debug/debug_logger.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py
Comment thread deeplabcut/core/debug/_debug_utils.py Outdated
Comment thread deeplabcut/gui/dialogs/debug_dialog.py
C-Achard added 5 commits May 13, 2026 11:24
Move the reload_debug_settings_from_env function from deeplabcut/core/debug/_debug_utils.py into deeplabcut/core/debug/debug_logger.py. The function (which reloads DLC_LOG_TIMING and DLC_LOG_TIMING_THRESHOLD_MS from environment variables) is removed from _debug_utils.py and added to debug_logger.py to colocate timing/debug env handling with the logging code. No behavioral changes intended.
Import QApplication and set an override WaitCursor in DebugTextDialog.refresh_text while calling the text provider, restoring the cursor in a finally block. This provides visual feedback during potentially long debug-text generation and ensures the cursor is always reset even if the provider raises an exception.
Allow the in-memory debug recorder to optionally auto-initialize the target logger's level. Import typing.Literal and change install_debug_recorder's ensure_logger_level parameter to accept None, int, or the new "auto" sentinel (default). Expand the docstring to document behavior: "auto" sets the logger to handler_level only when the logger has no explicit level (NOTSET); int lowers the logger level only if more restrictive; None leaves the logger untouched. Adjust the logic accordingly and update the GUI caller to pass handler_level and ensure_logger_level="auto" when installing the recorder.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.

Comment thread deeplabcut/gui/window.py Outdated
Comment thread deeplabcut/gui/dialogs/debug_dialog.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py
Comment thread deeplabcut/gui/dialogs/debug_dialog.py Outdated
Comment thread tests/core/debug/test_debug_logger.py
Comment thread deeplabcut/core/debug/debug_logger.py Outdated
Comment thread deeplabcut/core/debug/debug_logger.py
C-Achard and others added 4 commits May 15, 2026 14:14
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Convert libraries and executables to tuples in make_issue_report_provider so the returned provider can be called repeatedly even if given a one-shot iterable. Comment out redundant initial refresh_text() calls in the dialog (showEvent triggers the initial refresh). Also set logger.propagate = False in the test cleanup to avoid log propagation during tests.
Change install_debug_recorder to remove the special "auto" behavior for ensure_logger_level and make its default None; now only an int will lower the logger level when explicitly requested. Simplify some docstrings and clarify capacity wording. Add LibrarySpec.prefer_module_version and a new _module_version helper to prefer a module's __version__ when collecting versions (falling back to the distribution version if unavailable). Mark opencv-python to prefer the module version and update collect_version_summary to use the resolved module name for module paths.
Expose DebugSection from deeplabcut.core.debug by adding it to the module imports and __all__. Expand test_debug_logger.py with extensive tests for building and formatting debug reports, version and executable summaries, and log handling (using monkeypatched helpers and InMemoryDebugRecorder) to validate report contents and edge cases.
@C-Achard
C-Achard marked this pull request as ready for review May 15, 2026 15:29
@C-Achard
C-Achard requested a review from deruyter92 May 15, 2026 15:33
@deruyter92

Copy link
Copy Markdown
Collaborator

Thanks, this is going to make life easier! Will review next week.

@deruyter92 deruyter92 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just minor suggestions. Very helpful feature and nicely implemented!

Comment thread deeplabcut/gui/window.py Outdated
Comment thread deeplabcut/gui/dialogs/debug_dialog.py Outdated
Comment thread deeplabcut/gui/dialogs/debug_dialog.py Outdated
Comment thread deeplabcut/gui/dialogs/debug_dialog.py
Comment thread deeplabcut/gui/dialogs/debug_dialog.py Outdated
# https://github.com/DeepLabCut/DeepLabCut
#
# Please see AUTHORS for contributors.
# https://github.com/DeepLabCut/DeepLabCut/blob/master/AUTHORS

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# https://github.com/DeepLabCut/DeepLabCut/blob/master/AUTHORS
# https://github.com/DeepLabCut/DeepLabCut/blob/main/AUTHORS

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, should we replace all in a separate PR ?

Comment thread deeplabcut/core/debug/debug_logger.py Outdated
C-Achard added 2 commits May 18, 2026 11:37
Make InMemoryDebugRecorder.dropped_count thread-safe by acquiring the internal lock before returning the dropped counter to avoid race conditions (core/debug/debug_logger.py). In the main window, set ensure_logger_level to logging.INFO instead of the string "auto" to ensure the logger level is explicitly configured (gui/window.py). Minor GUI cleanup: update AUTHORS URL to the main branch, remove an unused TYPE_CHECKING stub and a redundant commented refresh call in the debug dialog (gui/dialogs/debug_dialog.py). These changes improve stability and tidy up UI code/comments.
@C-Achard
C-Achard merged commit eb4f848 into main May 18, 2026
30 checks passed
@C-Achard
C-Achard deleted the cy/debug-logger-ui branch May 18, 2026 15:15
@deruyter92 deruyter92 mentioned this pull request May 21, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request GUI issues relating to GUI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants