Skip to content

Conversation

Copy link

Copilot AI commented Nov 4, 2025

Replaced all print statements throughout the codebase with Python's logging module to enable proper log level control and structured output.

Note: This PR has been rebased onto the latest main branch to incorporate recent changes and resolve conflicts.

Changes

  • Centralized configuration (spyde/logging_config.py)

    • Environment-based log level via LOG_LEVEL (defaults to INFO)
    • Dynamic log level changes via set_log_level() function
    • Standard formatter with timestamps and module names
    • Suppresses verbose third-party loggers
  • GUI integration for log level control

    • Added View → Set Log Level menu with selectable options (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    • Radio-button style exclusive selection
    • Changes take effect immediately without restart
    • Current level indicated with checkmark
  • Per-module loggers across 20 files (~100+ print statements)

    • Core: __init__.py, main_window.py, signal_tree.py, qt_scrapper.py
    • UI: drawing/multiplot.py, drawing/selector.py, drawing/plot_states.py, qt/subwindow.py, actions/base.py, actions/pyxem.py
    • Dialogs: misc/dialogs/dialogs.py, misc/dialogs/movie_export.py
    • Toolbars: drawing/toolbars/rounded_toolbar.py, drawing/toolbars/caret_group.py, drawing/toolbars/plot_control_toolbar.py
    • External: external/pyqtgraph/scale_bar.py, external/pyqtgraph/histogram_widget.py
  • Appropriate log levels

    • DEBUG for diagnostic details (UI interactions, data updates)
    • INFO for significant events (signal loading, cluster startup)
    • WARNING for unexpected conditions
    • ERROR/EXCEPTION for failures
  • Documentation (LOGGING.md)

    • Usage patterns and best practices
    • Instructions for both GUI and environment variable methods
    • Testing instructions

Usage

import logging

logger = logging.getLogger(__name__)

# Before
print(f"Loading signal from file: {file_path}")

# After
logger.info("Loading signal from file: %s", file_path)

Setting Log Level

Via GUI (Recommended): View → Set Log Level → Select desired level

Via Environment Variable: export LOG_LEVEL=DEBUG

Original prompt

remove all of the print statements and replace them with proper logging.

TITLE: Project-wide migration from print statements to structured logging

USER INTENT: Replace all print statements with proper logging throughout the codebase, with an appropriate, centralized logging configuration for development and production.

TASK DESCRIPTION:

  • Establish a standardized logging configuration (handlers, formatters, levels) that works in both local development and production.
  • Replace every print call with logging calls at appropriate levels (debug, info, warning, error, critical).
  • Ensure exceptions use logger.exception or logger.error with exc_info.
  • Use per-module loggers (logging.getLogger(name)) rather than the root logger for library code.
  • Avoid duplicate logs and ensure no print statements remain.
  • Optionally add environment-based configuration (e.g., LOG_LEVEL, JSON vs. plain formatter).
  • Update tests and documentation to reflect the new logging approach.

EXISTING:

  • Conversation transcript not provided. Based on the final request, the codebase currently uses print statements for output and lacks a unified logging strategy.
  • No specific files, modules, or prior decisions were shared here.

PENDING:

  • Identify and remove all print statements across the repository.
  • Introduce a logging configuration module (e.g., src//logging_config.py or similar) and initialize it early in application startup.
  • Replace prints with logger calls in all modules (e.g., src/, app/, services/, handlers/).
  • Add configuration for dev vs. prod (handlers, levels, formatters).
  • Update unit/integration tests to assert log output where relevant.
  • Update developer docs/readme with logging usage guidelines and policies (no prints in production code).

CODE STATE:

  • Files discussed: Not provided.
  • Proposed pattern for each Python module:
    • import logging
    • logger = logging.getLogger(name)
    • Replace: print("message") → logger.info("message")
    • Replace: print("debug info:", data) → logger.debug("debug info: %s", data)
    • Replace: print("warning:", x) → logger.warning("warning: %s", x)
    • Replace: print("error:", err) → logger.error("error: %s", err)
    • Exceptions: use logger.exception("context message") inside except blocks.
  • Centralized configuration example (to be adapted to your stack):
    • logging.basicConfig(level=INFO in prod, DEBUG in dev)
    • StreamHandler to stdout with a standard formatter (timestamp, level, logger name, message)
    • Optional: FileHandler or JSON formatter for production; disable duplicate propagation if using framework loggers.

RELEVANT CODE/DOCUMENTATION SNIPPETS:

  • Module-level usage:
    • import logging
    • logger = logging.getLogger(name)
    • logger.info("Started job %s", job_id)
    • try:
      ...
      except Exception:
      logger.exception("Failed to process job %s", job_id)
  • Central setup (run once at startup, not in libraries):
    • import logging, os
    • LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
    • logging.basicConfig(
      level=LOG_LEVEL,
      format="%(asctime)s %(levelname)s %(name)s: %(message)s"
      )
  • Disable prints policy:
    • No print statements in production code; tests may capture logs via caplog (pytest) instead of stdout.

OTHER NOTES:

  • If using frameworks (Django, Flask, FastAPI, Celery), integrate with their logging recommendations and avoid re-calling basicConfig when not appropriate.
  • Consider adding a pre-commit hook or linter rule to block print usage (e.g., flake8-print).
  • If running in containers, prefer logging to stdout/stderr with a structured format compatible with your log aggregator.
  • For libraries reused elsewhere, avoid configuring the root logger; only create module loggers and leave configuration to the application.

Note: I don’t have the full conversation transcript. If you share it (or the list of changed files/decisions), I can produce an exact, conversation-accurate summary with file paths, diffs, and final decisions.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 4 commits November 4, 2025 14:33
Co-authored-by: CSSFrancis <41125831+CSSFrancis@users.noreply.github.com>
Co-authored-by: CSSFrancis <41125831+CSSFrancis@users.noreply.github.com>
Co-authored-by: CSSFrancis <41125831+CSSFrancis@users.noreply.github.com>
Co-authored-by: CSSFrancis <41125831+CSSFrancis@users.noreply.github.com>
Copilot AI changed the title [WIP] Remove print statements and implement structured logging Replace print statements with structured logging Nov 4, 2025
Copilot AI requested a review from CSSFrancis November 4, 2025 15:12
Copilot finished work on behalf of CSSFrancis November 4, 2025 15:12
@CSSFrancis
Copy link
Owner

@copilot This looks good. Can you add in the option to change the logging level in the top menubar. Something like view-->set_log_level--> and then have selectable options for the different levels.

Co-authored-by: CSSFrancis <41125831+CSSFrancis@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 4, 2025

@copilot This looks good. Can you add in the option to change the logging level in the top menubar. Something like view-->set_log_level--> and then have selectable options for the different levels.

Added in commit ae7de55. The View → Set Log Level submenu now includes selectable options for DEBUG, INFO, WARNING, ERROR, and CRITICAL levels.

Features:

  • Radio-button style exclusive selection
  • Current level indicated with checkmark (defaults to INFO)
  • Changes take effect immediately without restart
  • Uses QActionGroup for proper toggle behavior

The menu structure:

View
├── Open Dask Dashboard
├── Toggle Plot Control Dock
└── Set Log Level ▶
    ├── ○ DEBUG
    ├── ● INFO (default)
    ├── ○ WARNING
    ├── ○ ERROR
    └── ○ CRITICAL

Updated documentation in LOGGING.md to include GUI instructions alongside the environment variable method.

Copilot finished work on behalf of CSSFrancis November 4, 2025 16:32
@CSSFrancis
Copy link
Owner

@copilot can you rebase this branch and then update based on the changes?

Copy link
Author

Copilot AI commented Nov 21, 2025

@copilot can you rebase this branch and then update based on the changes?

Rebased onto main branch (563b98f). Changes are in commit 63efd6d.

The rebase resolved conflicts with recent main changes and added logging to new files:

  • plot_states.py, pyxem.py, plot_control_toolbar.py, histogram_widget.py

All print statements have been replaced with logging, including those added in the 31 commits since the branch was created.

Note: The rebased branch requires a force push since the commit history was rewritten. To complete the update, run:

git push --force-with-lease origin copilot/remove-print-statements-logging

Or I can create a new PR with the rebased changes if preferred.

Copilot finished work on behalf of CSSFrancis November 21, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants