Code Consistency - Logging & Standards

Check Python logging levels and patterns for correctness. Focus on identifying wrong severity levels and missing exception handling. Use when reviewing code quality.

allowed_tools: Read, Glob, Grep

$ Installer

git clone https://github.com/taylorsatula/mira-OSS /tmp/mira-OSS && cp -r /tmp/mira-OSS/.claude/skills/checking-code-consistency ~/.claude/skills/mira-OSS

// tip: Run this command in your terminal to install the skill


name: Code Consistency - Logging & Standards description: Check Python logging levels and patterns for correctness. Focus on identifying wrong severity levels and missing exception handling. Use when reviewing code quality. allowed-tools: Read, Glob, Grep

Code Consistency Checker

Scan Python files for logging issues. Flag incorrect severity levels and missing exception context.


Logging Level Decision Tree

Ask: What happened in this code?

Variable value, loop iteration, function entry/exit, detailed diagnostics?
  → DEBUG

Successful operation, workflow step completed, state change confirmed?
  → INFO

Unexpected but handled: fallback used, retry attempt, deprecated call, approaching limit?
  → WARNING

Functionality failed: operation error, caught exception, feature broken?
  → ERROR (use logger.exception() in except blocks)

System-wide failure: cannot serve requests, out of resources, imminent crash?
  → CRITICAL

Common Logging Mistakes

Wrong Severity Level

# ❌ WRONG: Exception logged as INFO
try:
    result = risky_operation()
except Exception as e:
    logger.info(f"Operation failed: {e}")  # Should be ERROR

# ✅ CORRECT: Use logger.exception() in except blocks
try:
    result = risky_operation()
except Exception as e:
    logger.exception("Operation failed")  # Automatically ERROR + stack trace
# ❌ WRONG: Normal operation logged as ERROR
user = get_user(user_id)
logger.error(f"Retrieved user {user_id}")  # Should be INFO or DEBUG

# ✅ CORRECT: Normal operations are INFO
user = get_user(user_id)
logger.info(f"Retrieved user {user_id}")
# ❌ WRONG: Fallback behavior logged as ERROR
cache_value = cache.get(key)
if cache_value is None:
    logger.error("Cache miss, using database")  # Should be WARNING or INFO
    value = db.query(key)

# ✅ CORRECT: Degraded mode is WARNING
cache_value = cache.get(key)
if cache_value is None:
    logger.warning("Cache miss, falling back to database")
    value = db.query(key)
# ❌ WRONG: Routine error logged as CRITICAL
if not user_id:
    logger.critical("Missing user_id parameter")  # Should be ERROR
    raise ValueError("user_id required")

# ✅ CORRECT: CRITICAL only for system-wide failures
if connection_pool_exhausted():
    logger.critical("Database connection pool exhausted, cannot serve requests")
    shutdown()

Missing Exception Context

# ❌ WRONG: Missing stack trace
try:
    process_data()
except Exception as e:
    logger.error(f"Failed: {e}")  # No stack trace

# ✅ CORRECT: Use logger.exception() or exc_info=True
try:
    process_data()
except Exception as e:
    logger.exception("Data processing failed")  # Includes stack trace

# ✅ ALSO CORRECT: Explicit exc_info
try:
    process_data()
except Exception as e:
    logger.error("Data processing failed", exc_info=True)

Logger Pattern Violations

# ❌ WRONG: Using root logger
logger = logging.getLogger()
logger.info("message")

# ✅ CORRECT: Named logger
logger = logging.getLogger(__name__)
logger.info("message")
# ❌ WRONG: Using print() for logging
print(f"Processing user {user_id}")

# ✅ CORRECT: Use logger
logger.info(f"Processing user {user_id}")

Security Issues

# ❌ WRONG: Logging sensitive data
logger.info(f"User authenticated: {username} / {password}")
logger.debug(f"API request: {api_key}")

# ✅ CORRECT: Redact sensitive information
logger.info(f"User authenticated: {username}")
logger.debug("API request authenticated")

Severity Level Guidelines

DEBUG (Development only, filter out in production)

  • Variable values during execution
  • Function entry/exit traces
  • Loop iteration details
  • Cache hits/misses (when debugging)
  • Query performance timing
  • Internal state inspection

Production: Set level to INFO or higher

INFO (Normal operations)

  • User logged in/out
  • Batch processing started/completed
  • Configuration loaded
  • Service started/stopped
  • Scheduled job executed
  • Workflow step completed
  • Major operation succeeded

If it's expected and good, it's INFO

WARNING (Unexpected but handled)

  • API rate limit approaching (80% capacity)
  • Deprecated function called
  • Retry attempt (N of M)
  • Using fallback/default value
  • Resource usage high but manageable
  • Temporary degradation

If it's weird but working, it's WARNING

ERROR (Functionality failed)

  • Database query failed
  • API call failed
  • File not found
  • Validation error
  • Tool execution failed
  • User operation failed
  • Any caught exception affecting functionality

Use logger.exception() in except blocks

CRITICAL (System failure)

  • Database unreachable
  • Out of memory
  • Connection pool exhausted
  • Authentication system down
  • Cannot serve requests
  • Imminent shutdown

Should trigger immediate alerts/paging


Check Execution

  1. Find all logger calls: logger.debug/info/warning/error/critical/exception()

  2. For each call, ask:

    • What situation triggered this log?
    • Does severity match the decision tree?
    • Is this in an except block? (should use logger.exception())
  3. Check patterns:

    • Named logger used? (getLogger(__name__))
    • No print() statements for operational logging?
    • No sensitive data logged?
  4. Flag issues with:

    • Line number
    • Current severity vs. correct severity
    • Reason for change

Output Format

FILE: path/to/file.py

LOGGING ISSUES:

Line 23: Severity too high
  Current: logger.error("Retrieved user data")
  Should be: logger.info("Retrieved user data")
  Reason: Normal successful operation should be INFO, not ERROR

Line 78: Missing exception context
  Current: logger.error(f"Failed: {e}")
  Should be: logger.exception("Operation failed")
  Reason: Use logger.exception() in except blocks for automatic stack trace

Line 134: Severity too low
  Current: logger.info("API call failed, retrying")
  Should be: logger.warning("API call failed, retrying")
  Reason: Retry indicates unexpected issue, should be WARNING

Line 201: Security violation
  Current: logger.debug(f"Authenticating with token: {api_token}")
  Should be: logger.debug("Authenticating with API")
  Reason: Never log credentials, tokens, or passwords

Line 234: Wrong logger pattern
  Current: logger = logging.getLogger()
  Should be: logger = logging.getLogger(__name__)
  Reason: Use named logger, not root logger

Line 289: Should use logger instead of print
  Current: print(f"Processing {count} items")
  Should be: logger.info(f"Processing {count} items")
  Reason: Use logging module for operational messages

SUMMARY: 6 logging issues found

Quick Reference Card

SituationLevelExample
Loop iteration detailsDEBUGlogger.debug(f"Processing item {i} of {total}")
Successful operationINFOlogger.info("Memory consolidation completed")
Fallback/retryWARNINGlogger.warning("Cache miss, using database")
Operation failedERRORlogger.exception("Failed to process data")
System cannot functionCRITICALlogger.critical("Database unreachable")

In except blocks: Always use logger.exception() or logger.error(..., exc_info=True)

Named logger: Always logger = logging.getLogger(__name__)

Security: Never log passwords, tokens, API keys, or PII