Practical Logging Solutions
Stratégie de journalisation complète
Développer une stratégie de journalisation solide implique de multiples composants et considérations pour garantir une surveillance et un débogage efficaces des applications.
Configuration de journalisation centralisée
import logging
import logging.config
import yaml
def setup_logging(config_path='logging.yaml'):
"""
Configure logging from YAML configuration file
"""
try:
with open(config_path, 'rt') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
except Exception as e:
print(f"Error loading logging configuration: {e}")
logging.basicConfig(level=logging.INFO)
Exemple de configuration de journalisation (YAML)
version: 1
formatters:
standard:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: standard
file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: standard
filename: app.log
maxBytes: 10485760
backupCount: 5
loggers:
"":
handlers: [console, file]
level: DEBUG
Comparaison des stratégies de journalisation
Stratégie |
Avantages |
Inconvénients |
Meilleur pour |
Journalisation en console (Console Logging) |
Simple, feedback immédiat |
Persistance limitée |
Développement |
Journalisation dans un fichier (File Logging) |
Enregistrements persistants |
Surcoût de performance |
Applications de petite à moyenne taille |
Journalisation centralisée (Centralized Logging) |
Mise à l'échelle possible, journaux agrégés |
Configuration complexe |
Systèmes distribués |
Décorateur de journalisation contextuelle
import logging
import functools
import contextvars
## Create a context variable for tracking request ID
request_id = contextvars.ContextVar('request_id', default='unknown')
def log_with_context(logger=None):
"""
Decorator to add contextual information to logs
"""
if logger is None:
logger = logging.getLogger(__name__)
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
extra = {
'request_id': request_id.get()
}
try:
logger.info(
f"Executing {func.__name__}",
extra=extra
)
result = func(*args, **kwargs)
logger.info(
f"{func.__name__} completed successfully",
extra=extra
)
return result
except Exception as e:
logger.exception(
f"Error in {func.__name__}",
extra=extra
)
raise
return wrapper
return decorator
Workflow de journalisation dans les systèmes distribués
graph TD
A[Client Request] --> B[Generate Request ID]
B --> C[Log Request Start]
C --> D[Service Processing]
D --> E[Log Intermediate Steps]
E --> F{Process Successful?}
F -->|Yes| G[Log Success]
F -->|No| H[Log Error]
G --> I[Return Response]
H --> I
Techniques avancées de journalisation
-
Journalisation structurée (Structured Logging)
- Utilisez des formats JSON ou clé-valeur
- Permet un parsing et une analyse plus faciles des journaux
-
Échantillonnage des journaux (Log Sampling)
- Réduit le volume de journalisation dans les applications à fort trafic
- Capture des entrées de journal représentatives
-
Ajustement dynamique du niveau de journalisation (Dynamic Log Level Adjustment)
- Modifiez les niveaux de journalisation à l'exécution
- Adaptez-vous à différents environnements
Implémentation pratique de la journalisation
import logging
from pythonjsonlogger import jsonlogger
class CustomJsonFormatter(jsonlogger.JsonFormatter):
def process_log_record(self, log_record):
## Add custom fields or transform existing ones
log_record['service'] = 'LabEx Application'
return log_record
def configure_json_logging():
logger = logging.getLogger()
json_handler = logging.StreamHandler()
formatter = CustomJsonFormatter(
'%(asctime)s %(levelname)s %(message)s %(request_id)s'
)
json_handler.setFormatter(formatter)
logger.addHandler(json_handler)
Bonnes pratiques
- Utilisez la journalisation structurée
- Implémentez la rotation des journaux
- Incluez des informations contextuelles
- Équilibrez la verbosité et les performances
- Utilisez des niveaux de journalisation appropriés
- Protégez les informations sensibles
En mettant en œuvre ces solutions pratiques de journalisation, les développeurs peuvent créer des applications plus observables et maintenables en utilisant les approches recommandées par LabEx.