FORMATION PYTHON

Formation Python

Année 2023

_

FORMATION PYTHON

Introduction au module 'Logging' en Python

Cette bibliothèque logging est inspirée des modules log4j ou log4cpp pour les langages Java ou C++.

Cela permet de construire des traces normalisées qui seront qualifiées et envoyées vers plusieurs sorties/destinations.

Voici un exemple:

import logging

logging.getLogger().setLevel(logging.INFO)

logging.info("hello")
logging.warning("Attention .....")
logging.error("Error ohlala!!")
logging.debug("pas vu, pas pris")

Ce qui donne ici:

INFO:root:hello
WARNING:root:Attention .....
ERROR:root:Error ohlala!!
FORMATION PYTHON

Le setlevel spcifie le niveau minimum des traces qui seront effectivement diffusées vers les sorties.
Les fonctions de traces .info, .warning, .error sont associées avec un niveau de trace interne. Seule la dernière trace ne sera pas visible car son niveau (ici logging.DEBUG) est inférieur au niveau de trace minimale.

Pour modifier le format d'affichage, il suffit de modifier la configuration de base via la fonction basicConfig du module.

import logging

STR_FMT = '%(asctime)s - %(levelname)s : %(message)s'
DATE_FMT = '%d/%m/%Y %H:%M:%S'

logging.basicConfig(datefmt=DATE_FMT,format=STR_FMT, level=logging.WARNING)
logger = logging.getLogger(__name__)

logger.info("hello")
logger.warning("Attention .....")
logger.error("Error ohlala!!")
logger.debug("Debug .......")

Ce qui donne ici, juste 2 traces:

24/01/2022 10:47:34 - WARNING : Attention .....
24/01/2022 10:47:34 - ERROR : Error ohlala!!
FORMATION PYTHON

Ce module très complet est organisé sous forme de classes dont voici les principales:

  • les handlers où destinations des traces.
  • les formatters qui définissemnt le contenu de chaque trace (horodatage, nopm de fichier, numéro de ligne, message ...).
  • les niveaux de traces.
  • des configurations via des fichiers externe (.ini, .yaml, ..).

Niveaux de traces

Les niveaux de trace correpondent à une valeur de référence. Lorsqu'un niveau est fixé au niveau d'une configuration, tous les messages de ce niveau ou d'un niveau supérieur sont vus, lus, enregistrés.

Dans l'exemple précédent, comme le level logging.WARNING est positionné, les messages de niveaux inférieurs comme debug et info ne seront pas diffusés. Un niveau de traces différent peut être associé à chaque handler.

Voir

FORMATION PYTHON

les handlers

Ces objets correspondent aux sorties/destinations où seront diffuès les messages. Plusieurs handlers peuvent être associés à un logger avec chacun leur propre niveau de trace et leur propre format de message (voir section suivante).

Il existe plusieurs types de handler:

  • handler fichiers
    • fichier simple.
    • fichier de taille fixe avec roulement (sur 7 fichiers par exemple).
    • fichier par période (Jour, semaine, année) avec roulement.
  • handler email.
  • handler réseaux (socket, datagram, tcp).
  • handler mémoire.
  • handler 'file de message'.
  • handler SGBD (distant ou SQLite).
FORMATION PYTHON

Pour manipuler et génér ces `handler' au niveau du logger, les méthodes suivantes sont disponibles:

  • addHandler
  • removeHandler

voir

Une interface est disponible pour créer ses propres handler, voir un exemple de handler 'base de données' avec: (https://github.com/onemoretime/mySQLHandler).

FORMATION PYTHON

Les formatters

Ces objects permettent de définir ce qui va apparaitre dans la trace. ils existent de nombreuses variables internes au module logging parmi:

Variables spéciales

Ces 2 variables correspondent, quand elles sont présentent, à la mise en forme de l'horodatage de la trace et au contenu spécifique du message

  • La variable interne 'asctime' spécifie le date-heure du message. Son format peut être redéfinie via un paramètre spécifique datefmt de la methode setFormatter
  • la variable interne 'message' qui renvoie sur le paramètre des methodes de creation de message comme:
FORMATION PYTHON

les fichiers de configuration

Il est possible de définir des loggers à travers de fichiers de configuration sous la forme de fichier de type 'ini' avec des sections.

Voici un exemple avec le contenu du fichier 'log.cfg':

#Logger config
[loggers]
keys=root

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=fileHandler,consoleHandler

[handler_fileHandler]
class=logging.handlers.TimedRotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=(os.path.join(os.getcwd(),'Logs','logger.log'), 'midnight', 1, 7)

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(funcName)20s - %(levelname)12s - %(thread)5s - %(message)s
datefmt=%d/%m/%Y %H:%M:%S
#end of logger config
FORMATION PYTHON

Ce fichier pourra être chargé avec la primitive configFile du module logging.config comme suit:

import logging
import logging.config
import logging.handler
import os

STR_FMT = '%(asctime)s - %(levelname)s : %(message)s'
DATE_FMT = '%d/%m/%Y %H:%M:%S'

try:
    logging.config.fileConfig(fname=os.path.join(os.getcwd(), 'log.cfg'))
    logger = logging.getLogger(__name__)
    logger.info("logger from file")
except Exception as e: # je ne trouve pas le fichier ou il y a une erreur au chargement
    logging.basicConfig(datefmt=DATE_FMT,format=STR_FMT, level=logging.INFO)
    logger = logging.getLogger(__name__)
    logger.warning(str(e))
    logger.info("logger from basicConfig")

logger.info("hello")
logger.warning("Attention .....")
logger.error("Error ohlala!!")
logger.critical("Ca craint")

Annexe

La docmentation officielle est très complète et décrit l'ensemble de tous les possibles, voir (https://docs.python.org/3/howto/logging.html)