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