Comment puis-je enregistrer mes erreurs Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Comment puis-je enregistrer mes erreurs Python?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
À utiliser logging.exception
depuis le except:
gestionnaire / bloc pour consigner l'exception en cours avec les informations de trace, précédées d'un message.
import logging
LOG_FILENAME = '/tmp/logging_example.out'
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
logging.debug('This message should go to the log file')
try:
run_my_stuff()
except:
logging.exception('Got exception on main handler')
raise
Vous voyez maintenant le fichier journal, /tmp/logging_example.out
:
DEBUG:root:This message should go to the log file
ERROR:root:Got exception on main handler
Traceback (most recent call last):
File "/tmp/teste.py", line 9, in <module>
run_my_stuff()
NameError: name 'run_my_stuff' is not defined
logger = logging.getLogger('yourlogger')
vous devez écrirelogger.exception('...')
pour que cela fonctionne ...Les
exc_info
options d' utilisation peuvent être meilleures, reste un avertissement ou un titre d'erreur:la source
exc_info=
s'appelle le kwarg; Merci!logging.exception
Mon travail m'a récemment chargé de consigner tous les retraits / exceptions de notre application. J'ai essayé de nombreuses techniques que d'autres avaient mises en ligne comme celle ci-dessus, mais j'ai opté pour une approche différente. Remplacer
traceback.print_exception
.J'ai un article sur http://www.bbarrows.com/ Ce serait beaucoup plus facile à lire mais je vais le coller ici également.
Lorsque j'ai été chargé de consigner toutes les exceptions que notre logiciel pourrait rencontrer dans la nature, j'ai essayé un certain nombre de techniques différentes pour enregistrer nos traces d'exceptions python. Au début, j'ai pensé que le hook d'exception du système python, sys.excepthook, serait l'endroit idéal pour insérer le code de journalisation. J'essayais quelque chose de similaire à:
Cela a fonctionné pour le thread principal, mais j'ai vite découvert que my sys.excepthook n'existerait pas sur les nouveaux threads démarrés par mon processus. C'est un problème énorme car presque tout se passe dans les threads de ce projet.
Après avoir cherché sur Google et lu beaucoup de documentation, les informations les plus utiles que j'ai trouvées provenaient du suivi des problèmes Python.
Le premier article sur le fil montre un exemple de travail du
sys.excepthook
NON persistant entre les fils (comme indiqué ci-dessous). Apparemment, c'est un comportement attendu.Les messages sur ce fil de discussion sur Python entraînent vraiment 2 hacks suggérés. Soit sous
Thread
-classez et encapsulez la méthode run dans notre propre bloc try except afin de capturer et enregistrer les exceptions, soit dans le patch monkeythreading.Thread.run
pour exécuter votre propre try except bloquer et enregistrer les exceptions.La première méthode de sous-classification
Thread
me semble moins élégante dans votre code car vous auriez à importer et utiliser votreThread
classe personnalisée PARTOUT où vous vouliez avoir un fil de journalisation. Cela a fini par être un problème car j'ai dû rechercher toute notre base de code et remplacer tout normalThreads
par cette coutumeThread
. Cependant, ce que cela faisait était clairThread
et il serait plus facile pour quelqu'un de diagnostiquer et de déboguer si quelque chose n'allait pas avec le code de journalisation personnalisé. Un thread de journalisation personnalisé peut ressembler à ceci:La deuxième méthode de patching de singe
threading.Thread.run
est agréable car je pourrais l'exécuter une fois juste après__main__
et instrumenter mon code de journalisation dans toutes les exceptions. Le correctif de singe peut être ennuyeux à déboguer car il change la fonctionnalité attendue de quelque chose. Le correctif suggéré par le suivi des problèmes Python était:Ce n'est que lorsque j'ai commencé à tester ma journalisation des exceptions que j'ai réalisé que tout allait mal.
Pour tester j'avais placé un
quelque part dans mon code. Cependant, encapsuler une méthode qui appelait cette méthode était un bloc try except qui imprimait le traçage et avalait l'exception. C'était très frustrant car j'ai vu le traçage apporter imprimé à STDOUT mais ne pas être journalisé. C'est alors que j'ai décidé qu'une méthode beaucoup plus simple de journalisation des retraits était simplement de corriger la méthode utilisée par tout le code python pour imprimer les retraits eux-mêmes, traceback.print_exception. J'ai fini avec quelque chose de similaire à ce qui suit:
Ce code écrit la traceback dans un tampon de chaîne et le consigne dans la journalisation ERROR. J'ai un gestionnaire de journalisation personnalisé configuré l'enregistreur «customLogger» qui prend les journaux de niveau ERREUR et les renvoie à la maison pour analyse.
la source
add_custom_print_exception
ne semble pas être sur le site auquel vous avez lié, et à la place, il y a un code final assez différent. Selon vous, lequel est le meilleur / le plus définitif et pourquoi? Merci!logger.error(traceback.format_tb())
(ou format_exc () si vous voulez aussi les informations d'exception).Vous pouvez enregistrer toutes les exceptions non interceptées sur le thread principal en affectant un gestionnaire à
sys.excepthook
, peut-être en utilisant leexc_info
paramètre des fonctions de journalisation de Python :Si votre programme utilise des threads, cependant, notez que les threads créés avec
threading.Thread
ne se déclencheront passys.excepthook
lorsqu'une exception non interceptée se produit à l'intérieur, comme indiqué dans le numéro 1230540 sur le suivi des problèmes de Python. Certains hacks ont été suggérés pour contourner cette limitation, comme le monkey-patchingThread.__init__
pour écraserself.run
avec unerun
méthode alternative qui enveloppe l'original dans untry
bloc et appellesys.excepthook
de l'intérieur duexcept
bloc. Alternativement, vous pouvez simplement envelopper manuellement le point d'entrée pour chacun de vos threads danstry
/except
yourself.la source
Les messages d'exception non capturés vont à STDERR, donc au lieu d'implémenter votre journalisation en Python lui-même, vous pouvez envoyer STDERR vers un fichier en utilisant le shell que vous utilisez pour exécuter votre script Python. Dans un script Bash, vous pouvez le faire avec la redirection de sortie, comme décrit dans le guide BASH .
Exemples
Ajouter les erreurs au fichier, autre sortie au terminal:
Écraser le fichier avec une sortie STDOUT et STDERR entrelacée:
la source
Ce que je cherchais:
Voir:
la source
Vous pouvez récupérer le traceback à l'aide d'un logger, à n'importe quel niveau (DEBUG, INFO, ...). Notez qu'en utilisant
logging.exception
, le niveau est ERROR.ÉDITER:
Cela fonctionne aussi (en utilisant python 3.6)
la source
Voici une version qui utilise sys.excepthook
la source
{traceback.format_exc()}
au lieu de{traceback.format_tb(stack)}
?peut-être pas aussi élégant, mais plus facile:
la source
Voici un exemple simple tiré de la documentation de python 2.6 :
la source