Plutôt que des print(), une alternative .... les logs
Natif de la bibliothèque Python, le module logging permet de faire de la journalisation. Appliqué à un simple débogage ou à une journalisation centralisée à partir de différents serveurs, ce module logging est un outil très utile.
La création d'un logger s'effectue en plusieurs étapes
- la création d'une instance
import logging
logger = logging.getLogger()
import logging
logger = logging.getLogger("myProg")
Si cette méthode n'a jamais été appelée auparavant dans le script le logger
est créé dans le cas contraire on récupère l'instance. Cela vous permet de récupérer celui-ci à
un autre endroit, sauf dans le cas entre plusieurs nœuds Python
(Dynamo) ou il faudra éventuellement se trimbaler la référence.
Note 1:
allez plutôt que de l'aspirine voici un petit logigramme en résumé 😀
voici la documentation complète sur le module logging
- définition du niveau du logger
logger.setLevel(logging.DEBUG)
Par défaut, il existe 5 niveaux standard indiquant la gravité des événements. Chacun a une méthode correspondante qui peut être utilisée pour consigner les événements à ce niveau de gravité. Les niveaux définis, par ordre de gravité croissante, sont les suivants :
|
Niveau des messages pris en compte |
|
|||||
Niveau de journalisation défini |
Méthode pour définir le niveau | DEBUG | INFO | WARNING | ERROR | CRITICAL | Méthode pour logger dans ce niveau |
DEBUG (10) | loggerOrHandler.setLevel(logging.DEBUG) | þ | þ | þ | þ | þ |
logger.debug('data in the list:' ) logger.debug(myList ) |
INFO (20) | loggerOrHandler.setLevel(logging.INFO) | ý | þ | þ | þ | þ | logger.info('INFO ERROR') |
WARNING (30) | loggerOrHandler.setLevel(logging.WARNING) | ý | ý | þ | þ | þ | logger.warning('This is a warning') |
ERROR (40) | loggerOrHandler.setLevel(logging.ERROR) | ý | ý | ý | þ | þ |
logger.error('This is a error :') logger.error(traceback.format_exc()) #except Exception as ex: logger.exception(ex) |
CRITICAL (50) | loggerOrHandler.setLevel(logging.CRITICAL) | ý | ý | ý | ý | þ |
logger.error('This is a critical error') #except Exception as ex: logger.exception(ex) |
- configuration du formateur
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
Plusieurs attributs sont disponibles Attribut formaté | Description |
%(asctime)s | Date au format « AAAA-MM-JJ HH:MM:SS,xxx ». Remarquons que nous disposons d'une précision à la milliseconde |
%(created)f | Idem précédent, mais avec une date en timestamp (utilisation de time.time()) |
%(filename)s | Nom du fichier ayant écrit dans le log |
%(funcName)s | Nom de la fonction contenant l'appel à l'écriture dans le log |
%(levelname)s | Niveau du message |
%(levelno)s | Numérotation logique du niveau du message (C:50, E:40, W:30, I:20, D:10) |
%(lineno)d | Ligne où trouver l'appel à écriture dans le log. Relatif au fichier d'appel |
%(module)s | Nom du module ayant appelé l'écriture dans le log |
%(msecs)d | Temps d'exécution depuis le lancement du programme en millisecondes |
%(message)s | Le message à logger |
%(name)s | Le nom de l'utilisateur courant |
%(pathname)s | Chemin absolu du fichier ayant appelé l'écriture |
%(process)d | Le numéro du process courant |
%(processName)s | Le nom du process courant |
%(thread)d | L'ID du thread courant |
%(threadName)s | Le nom du thread courant |
- création d'un handler
Logging handlers | Description |
StreamHandler |
envoi des messages aux flux (objets de type fichier)
Espace de Nom : logging |
FileHandler |
envoi des messages à des fichiers sur le disque Espace de Nom : logging |
RotatingFileHandler |
envoi des messages à des fichiers sur le disque, si le fichier
dépasse une certaine taille, renomme le fichier avec un compteur
puis ecrit un nouveau fichier Espace de Nom : logging.handlers |
TimedRotatingFileHandler |
envoi des messages aux fichiers de disque, en permutant le
fichier journal à intervalles réguliers. Espace de Nom : logging.handlers |
WatchedFileHandler |
surveillent le fichier sur lequel elles se connectent. Si le
fichier change, il est fermé et rouvert à l’aide du nom de fichier Espace de Nom: logging.handlers |
HTTPHandler |
envoi des messages à un serveur HTTP à l’aide de GET ou de
POST Espace de Nom : logging.handlers |
MemoryHandler |
envoi des messages à un tampon en mémoire, qui est vidé chaque
fois que des critères spécifiques sont remplis (transfert a un
autre handler ex: SMTPHandler) Espace de Nom : logging.handlers |
NTEventLogHandler |
envoi des messages à un journal des événements Windows Espace de Nommage : logging.handlers |
SysLogHandler |
envoi des messages à un daemon (serveur) syslog Espace de Nom : logging.handlers |
SocketHandler |
envoi des messages aux connecteurs TCP/IP Espace de Nom : logging.handlers |
DatagramHandler |
envoi des messages aux connecteurs UDP Espace de Nom : logging.handlers |
exemple :
import logging
from logging.handlers import RotatingFileHandler
from logging.handlers import SMTPHandler
logger = logging.getLogger('MyTracker')
# set root's level
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
#
# create handler
file_handler = RotatingFileHandler('activity.log', mode='a', maxBytes=1000000, backupCount=1)
# set level on DEBUG for this file_handler
file_handler.setLevel(logging.DEBUG)
# set formatter
file_handler.setFormatter(formatter)
# add this handler to logger
logger.addHandler(file_handler)
# add a second handler to logger with a different level
mailer = SMTPHandler(mailhost='myhost',
fromaddr='myadress_mail',
toaddrs=['send_mail1', 'send_mail2', 'send_mail3'],
subject='MyTracker',
credentials=('username','password'),
secure=None)
mailer.setLevel(logging.ERROR)
logger.addHandler(mailer)
Les niveaux des handlers peuvent être différent que le niveau principal.
- si le handler n'a pas de niveau défini, c'est le niveau du logger qui est pris en compte
- si le niveau d'un handler est inférieur au niveau du logger, c'est le niveau du logger qui devient prioritaire pour les messages (le setLevel() du handler ne sert a rien)
► on ne conserve que les messages associes au niveau du logger
- si le niveau d'un handler est supérieur au niveau du logger, on filtre un peu plus, c'est le niveau du handler qui devient prioritaire pour les messages
► on ne conserve que les messages associes au niveau du handler
Note 2:
Il existe 2 modes pour le FileHandler:mode = 'a' → pour 'append' ajoute la suite du log existant
mode = 'w' → pour 'write' écrase l'ancien log et écrit de nouveau
- on active ou on désactive le logger (optionnel)
logger.disabled = False #or True
-
et enfin
on print()on écrit nos logs
quelques exemples avec 2 handlers
tous les niveaux sont les mêmes (les setLevel() des handlers peuvent retirés) |
ici le niveau du file_handler est supérieur au niveau du logger, on ne conserve que les messages associés a ce niveau |
ici le niveau du stdout_handler est inférieur au niveau du logger, on ne conserve que les messages associés au niveau du logger |
allez plutôt que de l'aspirine voici un petit logigramme en résumé 😀
voici la documentation complète sur le module logging
Maintenant que vous avez tout compris on passe prochainement à la pratique...
0 commentaires:
Enregistrer un commentaire