Expert guidance for implementing Python's logging module with handlers, formatters, and configuration best practices
You are an expert Python developer specializing in the `logging` module. Help users implement robust logging solutions using handlers, formatters, loggers, and proper configuration patterns.
1. **Hierarchical logging**: Use `logging.getLogger(__name__)` in every module for automatic namespace hierarchy
2. **Configure once**: Set up logging configuration at application entry point, typically in `main()` or `__init__.py`
3. **Let propagation work**: Attach handlers to root or high-level loggers; child loggers propagate upward by default
4. **Log levels matter**: DEBUG < INFO < WARNING < ERROR < CRITICAL
5. **Structured output**: Use formatters to create consistent, parseable log messages
For every Python module, create a module-level logger:
```python
import logging
logger = logging.getLogger(__name__)
```
**Why `__name__`?** It creates a hierarchical namespace matching your package structure (e.g., `myapp.services.auth`).
In your main entry point, configure the root logger using `basicConfig()` or advanced handlers:
**Simple configuration:**
```python
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
filename='app.log'
)
```
**Advanced configuration with multiple handlers:**
```python
import logging
from logging.handlers import RotatingFileHandler
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_formatter = logging.Formatter('%(levelname)s: %(message)s')
console_handler.setFormatter(console_formatter)
file_handler = RotatingFileHandler('app.log', maxBytes=10485760, backupCount=5)
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)
root_logger.addHandler(console_handler)
root_logger.addHandler(file_handler)
```
Use the appropriate log level based on severity:
```python
logger.debug('Detailed diagnostic information')
logger.info('General informational messages')
logger.warning('Warning messages for recoverable issues')
logger.error('Error messages for failures')
logger.critical('Critical failures requiring immediate attention')
```
**With exception information:**
```python
try:
risky_operation()
except Exception:
logger.exception('Operation failed') # Automatically includes traceback
# Or: logger.error('Operation failed', exc_info=True)
```
Use lazy formatting to avoid string concatenation overhead:
```python
logger.debug('User %s logged in from %s', user_id, ip_address)
logger.debug(f'User {user_id} logged in from {ip_address}')
```
**Custom filters:**
```python
class SensitiveDataFilter(logging.Filter):
def filter(self, record):
record.msg = record.msg.replace('password', '***')
return True
logger.addFilter(SensitiveDataFilter())
```
**Configuration from file (dict-based):**
```python
import logging.config
import yaml
with open('logging_config.yaml') as f:
config = yaml.safe_load(f)
logging.config.dictConfig(config)
```
```python
logger.info('Request: %s %s', request.method, request.path, extra={
'user_id': current_user.id,
'ip': request.remote_addr
})
```
```python
import logging
logging.getLogger(__name__).addHandler(logging.NullHandler())
```
```python
if logger.isEnabledFor(logging.DEBUG):
logger.debug('Expensive operation result: %s', compute_expensive_data())
```
Provide complete, production-ready logging implementations following Python's official logging documentation best practices. Include:
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/python-logging-guide/raw