Logging Best Practices¶
Logging Levels¶
Use appropriate levels:
- DEBUG - Detailed diagnostic info (verbose, disabled in production)
- INFO - Key workflow steps, results, metrics
- WARNING - Unexpected conditions that were handled
- ERROR - Errors preventing operation completion
- CRITICAL - System failures
Logging Format¶
Always use %-formatting for performance:
# Good (lazy evaluation)
logger.info("Processed %d items in %.2fs", count, duration)
# Bad (eager evaluation even if not logged)
logger.info(f"Processed {count} items in {duration:.2f}s")
What to Log¶
Always Log¶
- File I/O operations (loading, saving)
- Major workflow steps (start/end of operations)
- Final results and metrics
- Warnings and errors
Use DEBUG Level¶
- Loop iterations
- Intermediate calculations
- Data shape/size details
- Detailed diagnostics
Don't Log¶
- Passwords, API keys, sensitive data
- Redundant information
- Every iteration of tight loops
Performance Logging¶
Use timing context managers:
from portfolio_management.core.logging_utils import log_execution_time
with log_execution_time("portfolio construction"):
portfolio = construct_portfolio(...)
# Logs: "Portfolio construction completed in 2.34s"
Progress Logging¶
For long operations, log progress:
from portfolio_management.core.logging_utils import ProgressLogger
progress = ProgressLogger(total=len(assets), operation="backtesting")
for asset in assets:
process(asset)
progress.update()
# Logs every 100 items: "Backtesting: 500/1000 (50.0%) - 43.2 items/sec"
Structured Logging¶
Use consistent formats for event types: