python.missing_structured_logging
Observability
Low
Detects print() statements for debugging or logging without structured format.
Why It Matters
Section titled “Why It Matters”Unstructured logs are hard to work with in production:
- Not searchable — Can’t query for specific fields
- Not aggregatable — Can’t count events by type
- Not alertable — Can’t set up alerts on specific conditions
- Parsing nightmares — Regex-based log parsing is fragile
Modern observability tools expect structured data with consistent fields.
Example
Section titled “Example”# ❌ Beforeprint(f"User {user_id} logged in")This is impossible to aggregate or alert on.
# ✅ Afterimport structlog
logger = structlog.get_logger()logger.info("user_logged_in", user_id=user_id)Now you can query event:user_logged_in and aggregate by user_id.
What Unfault Detects
Section titled “What Unfault Detects”print()statements (especially with variables)logging.info()etc. with string formatting instead of key-value pairs- Missing structured logging library imports
Auto-Fix
Section titled “Auto-Fix”Unfault converts print statements to structlog calls and adds the necessary imports.
Recommended Libraries
Section titled “Recommended Libraries”# structlog - Best for most casesimport structloglogger = structlog.get_logger()logger.info("event_name", key1=value1, key2=value2)
# python-json-logger - If you want JSON outputimport loggingfrom pythonjsonlogger import jsonlogger
logger = logging.getLogger()handler = logging.StreamHandler()handler.setFormatter(jsonlogger.JsonFormatter())logger.addHandler(handler)
# Standard library with extralogging.info("event", extra={"user_id": user_id})