File Handler
RichColorLog includes built-in file logging with level-based formatting.
Basic File Logging
Enable file logging with the log_file parameter:
from richcolorlog import setup_logging
logger = setup_logging(
log_file=True,
log_file_name='app.log',
log_file_level='DEBUG',
)
logger.info("This goes to console AND file")
logger.debug("Debug messages have detailed format in file")
Automatic Filename
If log_file_name is not specified, it auto-generates from your script name:
# In myapp.py
logger = setup_logging(log_file=True)
# Creates: myapp.log
# Or specify explicitly
logger = setup_logging(
log_file=True,
log_file_name='/var/log/myapp/application.log'
)
Level-Based Formatting
The file handler uses LevelBasedFileFormatter which applies different formats based on log level:
INFO and above:
2025-01-15 10:30:45,123 - INFO - myapp - User logged in (auth.py:42)
DEBUG:
2025-01-15 10:30:45,123 - DEBUG - myapp - 12345 - 140123456789 - authenticate - Processing credentials (auth.py:38)
The DEBUG format includes:
Process ID
Thread ID
Function name
Full pathname
File Handler Configuration
Parameter |
Default |
Description |
|---|---|---|
|
|
Enable file logging |
|
Auto-generated |
Path to log file |
|
|
Minimum level for file logging |
Example Configurations
Development
logger = setup_logging(
level='DEBUG',
log_file=True,
log_file_name='debug.log',
log_file_level='DEBUG', # Capture everything
)
Production
logger = setup_logging(
level='INFO',
log_file=True,
log_file_name='/var/log/myapp/app.log',
log_file_level='INFO', # Skip debug in file too
)
Separate Files by Level
import logging
from richcolorlog import setup_logging
logger = setup_logging(name='myapp', level='DEBUG')
# Error log
error_handler = logging.FileHandler('error.log')
error_handler.setLevel(logging.ERROR)
error_handler.setFormatter(logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s'
))
logger.addHandler(error_handler)
# Debug log
debug_handler = logging.FileHandler('debug.log')
debug_handler.setLevel(logging.DEBUG)
logger.addHandler(debug_handler)
Rotating File Handler
For production, use rotating handlers to manage file size:
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
from richcolorlog import setup_logging
from richcolorlog.logger import LevelBasedFileFormatter
logger = setup_logging(name='myapp', level='DEBUG')
# Size-based rotation
rotating_handler = RotatingFileHandler(
'app.log',
maxBytes=10*1024*1024, # 10MB
backupCount=5
)
rotating_handler.setFormatter(LevelBasedFileFormatter())
logger.addHandler(rotating_handler)
# Time-based rotation (daily)
timed_handler = TimedRotatingFileHandler(
'app.log',
when='midnight',
interval=1,
backupCount=30
)
timed_handler.setFormatter(LevelBasedFileFormatter())
logger.addHandler(timed_handler)
Custom File Formatter
Create custom formatters for file output:
import logging
from richcolorlog import setup_logging
class JSONFormatter(logging.Formatter):
def format(self, record):
import json
log_entry = {
'timestamp': self.formatTime(record),
'level': record.levelname,
'logger': record.name,
'message': record.getMessage(),
'module': record.module,
'function': record.funcName,
'line': record.lineno,
}
return json.dumps(log_entry)
logger = setup_logging(name='myapp')
json_handler = logging.FileHandler('app.json')
json_handler.setFormatter(JSONFormatter())
logger.addHandler(json_handler)
File Encoding
Always specify encoding for non-ASCII content:
import logging
from richcolorlog import setup_logging
logger = setup_logging(name='myapp')
handler = logging.FileHandler('app.log', encoding='utf-8')
logger.addHandler(handler)
logger.info("Unicode: こんにちは 🎉")
Best Practices
Use absolute paths in production
log_file_name='/var/log/myapp/app.log'
Set appropriate permissions
sudo mkdir -p /var/log/myapp sudo chown appuser:appgroup /var/log/myapp
Use rotation for long-running services
Consider separate files for different severity levels
Include enough context in log messages
logger.info(f"User {user_id} performed {action} on {resource}")