Source code for gratools.logger_config

import logging
import logging.config
import click
from pathlib import Path
import sys

from rich import get_console
from rich.traceback import install, Traceback
from rich.console import Console

# Définir des couleurs pour les différents niveaux de log
available_colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white',
                    'bright_black', 'bright_red', 'bright_green', 'bright_yellow', 'bright_blue', 'bright_magenta', 'bright_cyan', 'bright_white']

# https://click.palletsprojects.com/en/8.1.x/api/#click.style
LOG_COLORS = {
    'DEBUG': 'magenta',
    'INFO': 'cyan',
    'WARNING': 'yellow',
    'ERROR': 'red',
    'CRITICAL': 'bright_red',
    'FATAL': 'bright_red',
}

# Classe personnalisée pour ajouter des couleurs aux messages de log
[docs] class ColoredFormatter(logging.Formatter): def __init__(self, fmt, datefmt, debug, verbosity): super().__init__(fmt, datefmt) self.debug = debug self.verbosity = verbosity
[docs] def format(self, record): # Formatage de l'exception si présente traceback_message = None log_message = super().format(record) colored_log_message = click.style(log_message, fg=LOG_COLORS.get(record.levelname, 'white')) # Ajouter le texte de l'exception formatée uniquement pour le mode DEBUG if self.verbosity == 'DEBUG' and record.exc_info: # Utiliser rich.Traceback pour formater l'exception traceback = Traceback.from_exception(*record.exc_info) console = get_console() or Console() with console.capture() as capture: console.print(traceback) traceback_message = capture.get() log_message = colored_log_message if traceback_message: log_message = traceback_message + "\n" + colored_log_message # Interrompre le programme en cas d'erreur critique ou fatale if record.levelno >= logging.ERROR: sys.exit(f"{log_message}\n") return log_message
[docs] def formatException(self, exc_info): return ""
[docs] def configure_logger(name, log_path, verbosity): basenameLog = Path(log_path).joinpath(f"{name}_log") debug = False verbosity = verbosity.upper() if verbosity == 'DEBUG': debug = True install(show_locals=True) # Installer rich.traceback logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': f'%(asctime)s | {"%(name)-8s | %(funcName)-22s |" if debug else ""} %(levelname)-8s | %(message)s', 'datefmt': '%m-%d %H:%M', }, 'colored': { '()': lambda: ColoredFormatter( f'%(asctime)s | {"%(name)-8s | %(funcName)-22s |" if debug else ""} %(levelname)-8s | %(message)s', '%m-%d %H:%M', debug, verbosity ), }, }, 'handlers': { 'stdout_handler': { 'level': verbosity, 'class': 'logging.StreamHandler', 'formatter': 'colored', 'stream': 'ext://sys.stdout', }, 'logHandler': { 'level': verbosity, 'filename': f"{basenameLog}.o", 'class': 'logging.FileHandler', 'formatter': 'standard', 'mode': 'w', }, 'errorLogHandler': { 'level': 'WARNING', 'filename': f"{basenameLog}.e", 'class': 'logging.FileHandler', 'formatter': 'standard', 'mode': 'w', }, }, 'loggers': { "": { 'handlers': ['stdout_handler', 'logHandler', 'errorLogHandler'], 'level': verbosity, 'propagate': True, }, } }) return logging.getLogger(name)
[docs] def update_logger_file_paths(logger, new_log_path, name): basenameLog = Path(new_log_path).joinpath(f"{name}_log") # Remplacer les gestionnaires de fichiers existants par de nouveaux gestionnaires for handler in logger.handlers: if isinstance(handler, logging.FileHandler): if handler.level == logging.WARNING: new_handler = logging.FileHandler(f"{basenameLog}.e", mode='w') else: new_handler = logging.FileHandler(f"{basenameLog}.o", mode='w') new_handler.setFormatter(handler.formatter) new_handler.setLevel(handler.level) logger.removeHandler(handler) logger.addHandler(new_handler)
# Exemple d'utilisation if __name__ == "__main__": logger = configure_logger('my_logger', '.', 'DEBUG') try: # Code qui peut générer une exception 1 / 0 except Exception as e: logger.error("An error occurred", exc_info=True)