Voici la documentation : https://geoplateforme.pages.gpf-tech.ign.fr/documentation

Skip to content
Extraits de code Groupes Projets

Draft: Corrige et améliore le logger en utilisant un adaptateur

Ouvert Julien Moura a demandé de fusionner feature/use-logging-adapter vers main
Fichiers
2
#! python3 # noqa: E265
"""Logueur pour la GPF."""
"""Loggueur personnalisé correspondant aux exigences de l'API Entrepôt de la GPF."""
# #############################################################################
# ########## Libraries #############
# ##################################
# Standard library
import logging
# #############################################################################
# ########## Globals ###############
# ##################################
log_fmt_base = logging.Formatter(
fmt="%(asctime)s||%(levelname)s||%(module)s||%(lineno)d||%(message)s",
)
log_fmt_user = logging.Formatter(
fmt="%(asctime)s||%(levelname)s||USER||%(module)s||%(lineno)d||%(message)s",
)
opt_log_user = {"user": True}
# #############################################################################
# ########## Classes ###############
# ##################################
class GpfLogAdapter(logging.LoggerAdapter):
"""Classe permettant d'adapter un logger au fonctionnement de l'API Entrepôt.
Args:
logging (logging.LoggerAdapter): _description_
"""
def process(self, msg: str, kwargs: dict) -> tuple[str, dict]:
"""Traite les messages à journaliser.
Args:
msg (str): message à journaliser
kwargs (dict): paramètres optionnels passés sous forme de dictionnaire
Returns:
tuple[str, dict]: message formaté and dictionnaire d'options
"""
if (
"extra" in kwargs
and "user" in kwargs.get("extra", [])
and kwargs.get("extra").get("user", False) is True
):
self.logger.handlers[0].setFormatter(log_fmt_user)
else:
self.logger.handlers[0].setFormatter(log_fmt_base)
return msg, kwargs
class GPFFormatter(logging.Formatter):
def format(self, record):
@@ -18,56 +68,66 @@ class GPFFormatter(logging.Formatter):
return super().format(record)
def add_logging_level(levelName, levelNum, methodName=None):
"""
Comprehensively adds a new logging level to the `logging` module and the
currently configured logging class.
# #############################################################################
# ########## Functions #############
# ##################################
`levelName` becomes an attribute of the `logging` module with the value
`levelNum`. `methodName` becomes a convenience method for both `logging`
itself and the class returned by `logging.getLoggerClass()` (usually just
`logging.Logger`). If `methodName` is not specified, `levelName.lower()` is
used.
To avoid accidental clobberings of existing attributes, this method will
raise an `AttributeError` if the level name is already an attribute of the
def add_logging_level(
log_level_name: str, log_level_number: int, log_method_name: str = None
):
"""Ajoute un niveau de journalisation personnalisé au module `logging`.
La valeur `log_level_name` devient un attribut du module `logging` avec la valeur \
`log_level_number`. `log_method_name` devient une méthode pour logguer facilement.
Source : https://stackoverflow.com/a/35804945
Args:
log_level_name (str): nom du niveau de log à ajouter.
log_level_number (int): nombre correspondant au niveau de log
log_method_name (str, optional): nom de la méthode d'appel. If None,
`log_level_name.lower()` is used. Defaults to None.
Raises:
an: _description_
AttributeError: if the level name is already an attribute of the
`logging` module or if the method name is already present
Example
-------
>>> addLoggingLevel('TRACE', logging.DEBUG - 5)
>>> logging.getLogger(__name__).setLevel("TRACE")
>>> logging.getLogger(__name__).trace('that worked')
>>> logging.trace('so did this')
>>> logging.TRACE
5
Example:
.. code-block:: python
From: https://stackoverflow.com/a/35804945
>>> addLoggingLevel('TRACE', logging.DEBUG - 5)
>>> logging.getLogger(__name__).setLevel("TRACE")
>>> logging.getLogger(__name__).trace('that worked')
>>> logging.trace('so did this')
>>> logging.TRACE
>>> 5
"""
if not methodName:
methodName = levelName.lower()
if not log_method_name:
log_method_name = log_level_name.lower()
if hasattr(logging, levelName):
raise AttributeError(f"{levelName} already defined in logging module")
if hasattr(logging, methodName):
raise AttributeError(f"{methodName} already defined in logging module")
if hasattr(logging.getLoggerClass(), methodName):
raise AttributeError(f"{methodName} already defined in logger class")
if hasattr(logging, log_level_name):
raise AttributeError(f"{log_level_name} already defined in logging module")
if hasattr(logging, log_method_name):
raise AttributeError(f"{log_method_name} already defined in logging module")
if hasattr(logging.getLoggerClass(), log_method_name):
raise AttributeError(f"{log_method_name} already defined in logger class")
# This method was inspired by the answers to Stack Overflow post
# http://stackoverflow.com/q/2183233/2988730, especially
# http://stackoverflow.com/a/13638084/2988730
def logForLevel(self, message, *args, **kwargs):
if self.isEnabledFor(levelNum):
self._log(levelNum, message, args, **kwargs)
if self.isEnabledFor(log_level_number):
self._log(log_level_number, message, args, **kwargs)
def logToRoot(message, *args, **kwargs):
logging.log(levelNum, message, *args, **kwargs)
logging.log(log_level_number, message, *args, **kwargs)
logging.addLevelName(levelNum, levelName)
setattr(logging, levelName, levelNum)
setattr(logging.getLoggerClass(), methodName, logForLevel)
setattr(logging, methodName, logToRoot)
logging.addLevelName(log_level_number, log_level_name)
setattr(logging, log_level_name, log_level_number)
setattr(logging.getLoggerClass(), log_method_name, logForLevel)
setattr(logging, log_method_name, logToRoot)
def gpf_logger_script(verbosity: int, title: str) -> logging.Logger:
@@ -82,14 +142,15 @@ def gpf_logger_script(verbosity: int, title: str) -> logging.Logger:
"""
# Define default config for date format
logging.basicConfig(
datefmt="%Y-%m-%d %H:%M:%S",
)
# logging.basicConfig(
# datefmt="%Y-%m-%d %H:%M:%S",
# )
# Add console for logger
console = logging.StreamHandler()
console.setFormatter(GPFFormatter())
console.setFormatter(log_fmt_base)
console.setLevel(verbosity)
console = GpfLogAdapter(console, extra={"user": False})
# Remove all handlers for root logger to avoid multiple log in console
logging.getLogger().handlers.clear()
Chargement en cours