You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

3.0 KiB

title category severity
Logging Constraints constraints critical

Logging Constraints

Core Rule

Use logging.getLogger(__name__) - never use print()

CRITICAL ANTI-PATTERN: api_client.py uses print() instead of logging (11 instances).

CRITICAL Anti-Pattern: print() Instead of Logging

File: api_client.py Evidence: Lines with print(f"...") instead of _logger.info(...)

Broken code:

def get_motions(self, ...):
    try:
        # ...
        print(f"Fetched {len(voting_records)} voting records from API")  # BAD
        print(f"Processed into {len(motions)} unique motions")  # BAD
    except Exception as e:
        print(f"Error fetching motions from API: {e}")  # BAD - no traceback

Fix:

import logging

_logger = logging.getLogger(__name__)

def get_motions(self, ...):
    try:
        _logger.info("Fetched %d voting records from API", len(voting_records))
        _logger.info("Processed into %d unique motions", len(motions))
    except Exception as e:
        _logger.exception("Error fetching motions from API: %s", e)
        return []

Logger Initialization

Get logger at module level:

# GOOD: Use logging.getLogger(__name__)
import logging

_logger = logging.getLogger(__name__)

def some_function():
    _logger.info("Processing started")
    _logger.debug("Detail: %s", detail)

Logger Naming

Use __name__ for automatic module path:

# In database.py - logger will be "database"
_logger = logging.getLogger(__name__)

# In pipeline/svd_pipeline.py - logger will be "pipeline.svd_pipeline"
_logger = logging.getLogger(__name__)

INCONSISTENCY WARNING: 16 files use logger, 17 files use _logger. Choose one convention.

Recommendation: Use _logger (with underscore) for module-level loggers to distinguish from class-level loggers.

Log Levels

Level When to Use
DEBUG Detailed diagnostic info (dev only)
INFO Normal operation milestones
WARNING Unexpected but handled (fallbacks)
ERROR Operation failed, may need attention
CRITICAL Fatal error, program may crash

Exception Logging

Use _logger.exception() for caught exceptions (includes traceback):

try:
    result = risky_operation()
except Exception as exc:
    _logger.exception("Operation failed: %s", exc)
    return fallback_value

Anti-Patterns

Debug Prints in Production Code

# BAD
print(f"[TRAJ DEBUG] processing window {wid}")

# GOOD
_logger.debug("Processing window %s", wid)

Inconsistent Logger Names

# BAD - mixing _logger and logger
_logger = logging.getLogger(__name__)
logger = logging.getLogger("other")  # Inconsistent

Sensitive Data

Never log sensitive information:

  • API keys
  • User votes
  • Session IDs (if tied to user data)
  • Personal information
# BAD
_logger.info("User %s voted %s", user_id, vote)

# GOOD - log aggregates, not individual votes
_logger.info("Vote recorded for session %s", session_id[:8])