113 lines
3.2 KiB
Python
Executable File
113 lines
3.2 KiB
Python
Executable File
"""
|
|
Configuration du système de logging pour PriceWatch.
|
|
|
|
Fournit un logger configuré avec formatage coloré et niveaux appropriés.
|
|
Les logs incluent : timestamp, niveau, module, et message.
|
|
"""
|
|
|
|
import logging
|
|
import sys
|
|
from typing import Optional
|
|
|
|
|
|
class ColoredFormatter(logging.Formatter):
|
|
"""Formatter avec couleurs pour améliorer la lisibilité en CLI."""
|
|
|
|
# Codes ANSI pour les couleurs
|
|
COLORS = {
|
|
"DEBUG": "\033[36m", # Cyan
|
|
"INFO": "\033[32m", # Vert
|
|
"WARNING": "\033[33m", # Jaune
|
|
"ERROR": "\033[31m", # Rouge
|
|
"CRITICAL": "\033[35m", # Magenta
|
|
}
|
|
RESET = "\033[0m"
|
|
BOLD = "\033[1m"
|
|
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
"""Formate le log avec couleurs selon le niveau."""
|
|
# Copie pour éviter de modifier l'original
|
|
log_color = self.COLORS.get(record.levelname, self.RESET)
|
|
record.levelname = f"{log_color}{self.BOLD}{record.levelname}{self.RESET}"
|
|
|
|
# Colorer le nom du module
|
|
record.name = f"\033[90m{record.name}{self.RESET}"
|
|
|
|
return super().format(record)
|
|
|
|
|
|
def setup_logging(level: str = "INFO", enable_colors: bool = True) -> logging.Logger:
|
|
"""
|
|
Configure le logger racine de PriceWatch.
|
|
|
|
Args:
|
|
level: Niveau de log (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
enable_colors: Activer la colorisation (désactiver pour les logs fichier)
|
|
|
|
Returns:
|
|
Logger configuré
|
|
|
|
Justification technique:
|
|
- Handler unique sur stdout pour éviter les duplications
|
|
- Format détaillé avec timestamp ISO8601 pour faciliter le debug
|
|
- Colorisation optionnelle pour améliorer l'UX en CLI
|
|
"""
|
|
logger = logging.getLogger("pricewatch")
|
|
|
|
# Éviter d'ajouter plusieurs handlers si appelé plusieurs fois
|
|
if logger.handlers:
|
|
return logger
|
|
|
|
logger.setLevel(getattr(logging, level.upper(), logging.INFO))
|
|
logger.propagate = False
|
|
|
|
# Handler console
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(logger.level)
|
|
|
|
# Format avec timestamp ISO8601
|
|
log_format = "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s"
|
|
date_format = "%Y-%m-%d %H:%M:%S"
|
|
|
|
if enable_colors and sys.stdout.isatty():
|
|
formatter = ColoredFormatter(log_format, datefmt=date_format)
|
|
else:
|
|
formatter = logging.Formatter(log_format, datefmt=date_format)
|
|
|
|
console_handler.setFormatter(formatter)
|
|
logger.addHandler(console_handler)
|
|
|
|
return logger
|
|
|
|
|
|
def get_logger(name: Optional[str] = None) -> logging.Logger:
|
|
"""
|
|
Retourne un logger enfant de 'pricewatch'.
|
|
|
|
Args:
|
|
name: Nom du sous-module (ex: 'scraping.http')
|
|
|
|
Returns:
|
|
Logger configuré
|
|
"""
|
|
if name:
|
|
return logging.getLogger(f"pricewatch.{name}")
|
|
return logging.getLogger("pricewatch")
|
|
|
|
|
|
def set_level(level: str) -> None:
|
|
"""
|
|
Change dynamiquement le niveau de log.
|
|
|
|
Args:
|
|
level: Nouveau niveau (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
"""
|
|
logger = logging.getLogger("pricewatch")
|
|
logger.setLevel(getattr(logging, level.upper(), logging.INFO))
|
|
for handler in logger.handlers:
|
|
handler.setLevel(logger.level)
|
|
|
|
|
|
# Initialisation par défaut au premier import
|
|
_default_logger = setup_logging()
|