Comment enregistrer le nom du fichier source et le numéro de ligne en Python
123
Est-il possible de décorer / étendre le système de journalisation standard python, de sorte que lorsqu'une méthode de journalisation est invoquée, elle enregistre également le fichier et le numéro de ligne où elle a été invoquée ou peut-être la méthode qui l'a invoquée?
Et, oui, le désordre majuscules / minuscules dans les variables doit être pris en compte.
Tom Pohl
1
Autrement appelé "cas de chameau très mal mis en œuvre".
Jon Spencer
81
En plus de la réponse très utile de Seb , voici un extrait de code pratique qui montre l'utilisation de l'enregistreur avec un format raisonnable:
#!/usr/bin/env pythonimport logging
logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
datefmt='%Y-%m-%d:%H:%M:%S',
level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")
logger.critical("This is critical")
logger.error("An error occurred")
Génère cette sortie:
2017-06-06:17:07:02,158 DEBUG [log.py:11]Thisis a debug log
2017-06-06:17:07:02,158 INFO [log.py:12]Thisis an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13]Thisis critical
2017-06-06:17:07:02,158 ERROR [log.py:14]An error occurred
Utilisez ceci pour plus de détails: formatter = logging.Formatter ('% (asctime) s,% (levelname) -8s [% (filename) s:% (module) s:% (funcName) s:% (lineno) d] % (message) s ')
Girish Gupta
y a-t-il un moyen de changer juste à un endroit en haut du code, que les messages de journalisation soient imprimés ou non? Je voudrais deux modes, un avec beaucoup d'impressions pour voir exactement ce que fait le programme; et un, lorsqu'il est suffisamment stable, où aucune sortie n'est affichée.
Marie. P.
3
@ Marie.P. ne posez pas de questions différentes dans les commentaires. La réponse réside cependant dans les niveaux de journalisation.
bugmenot123
4
Pour construire sur ce qui précède d'une manière qui envoie la journalisation de débogage à la sortie standard:
import logging
import sys
root = logging.getLogger()
root.setLevel(logging.DEBUG)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
FORMAT ="[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
formatter = logging.Formatter(FORMAT)
ch.setFormatter(formatter)
root.addHandler(ch)
logging.debug("I am sent to standard out.")
Mettre ce qui précède dans un fichier appelé debug_logging_example.pyproduit la sortie:
[debug_logging_example.py:14-<module>()] I am sent to standard out.
Ensuite, si vous souhaitez désactiver la déconnexion des commentaires root.setLevel(logging.DEBUG).
Pour les fichiers uniques (par exemple les affectations de classe), j'ai trouvé que c'était une bien meilleure façon de faire cela que d'utiliser des print()instructions. Où il vous permet de désactiver la sortie de débogage en un seul endroit avant de la soumettre.
Pour les développeurs utilisant PyCharm ou Eclipse pydev, ce qui suit produira un lien vers la source de l'instruction de journal dans la sortie du journal de la console:
import logging, sys, os
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(message)s | \'%(name)s:%(lineno)s\'')
log = logging.getLogger(os.path.basename(__file__))
log.debug("hello logging linked to source")
# your imports above ...
logging.basicConfig(
format='%(asctime)s,%(msecs)d %(levelname)-8s [%(pathname)s:%(lineno)d in
function %(funcName)s] %(message)s',
datefmt='%Y-%m-%d:%H:%M:%S',
level=logging.DEBUG
)
logger = logging.getLogger(__name__)# your classes and methods below ...# An naive Sample of usage:try:
logger.info('Sample of info log')# your code hereexceptExceptionas e:
logger.error(e)
Différente des autres réponses, cela enregistrera le chemin complet du fichier et le nom de la fonction qui aurait pu provoquer une erreur. Ceci est utile si vous avez un projet avec plus d'un module et plusieurs fichiers avec le même nom répartis dans ces modules.
En plus de la réponse très utile de Seb , voici un extrait de code pratique qui montre l'utilisation de l'enregistreur avec un format raisonnable:
Génère cette sortie:
la source
Pour construire sur ce qui précède d'une manière qui envoie la journalisation de débogage à la sortie standard:
Mettre ce qui précède dans un fichier appelé
debug_logging_example.py
produit la sortie:Ensuite, si vous souhaitez désactiver la déconnexion des commentaires
root.setLevel(logging.DEBUG)
.Pour les fichiers uniques (par exemple les affectations de classe), j'ai trouvé que c'était une bien meilleure façon de faire cela que d'utiliser des
print()
instructions. Où il vous permet de désactiver la sortie de débogage en un seul endroit avant de la soumettre.la source
Pour les développeurs utilisant PyCharm ou Eclipse pydev, ce qui suit produira un lien vers la source de l'instruction de journal dans la sortie du journal de la console:
Voir les hyperliens du fichier source Pydev dans la console Eclipse pour une discussion et un historique plus longs.
la source
Différente des autres réponses, cela enregistrera le chemin complet du fichier et le nom de la fonction qui aurait pu provoquer une erreur. Ceci est utile si vous avez un projet avec plus d'un module et plusieurs fichiers avec le même nom répartis dans ces modules.
la source