Skip to main content
Logging is a means of tracking events that happen when software runs. It’s essential for debugging, monitoring, and understanding application behavior.

When to Use Logging

Quick Start

Logging Levels

Levels in order of severity:

Logging to Files

Basic File Logging

File Modes

Format Strings

Common Format Attributes

Useful attributes:
  • %(name)s - Logger name
  • %(levelname)s - Logging level
  • %(message)s - Log message
  • %(asctime)s - Timestamp
  • %(filename)s - Source filename
  • %(lineno)d - Line number
  • %(funcName)s - Function name
  • %(process)d - Process ID
  • %(thread)d - Thread ID

Custom Formatting

Output:

Variable Data

Using Format Strings

Don’t format strings manually:

Advanced Configuration

Exception Logging

Log Exceptions with Traceback

Output:

Log Without Traceback

Logger Hierarchy

Parent-Child Relationships

Best Practice: Module-Level Loggers

Configuration Files

INI Format

Load configuration:

Dictionary Configuration

Library Logging

For Library Authors

Library Best Practices:
  • Use logging.getLogger(__name__) in each module
  • Add NullHandler() to prevent warnings
  • Never configure handlers in library code
  • Document what loggers your library uses

Common Patterns

Conditional Expensive Operations

Context Information

Web Request Logging

Troubleshooting

Common Issues:
  1. Duplicate logs: Check if multiple handlers are added
  2. No output: Verify logger level and handler level
  3. Wrong format: Check both handler and logger formatters
  4. File not created: Check permissions and path

Debug Logging Setup

Summary

Key takeaways:
  1. Use logger = logging.getLogger(__name__) in each module
  2. Configure logging once at application entry point
  3. Use appropriate log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  4. Never add handlers in library code
  5. Use logger.exception() in except blocks
  6. Format messages with placeholders, not string concatenation