736 votes

Comment puis-je enregistrer une erreur Python avec des informations de débogage?

Je suis en train d'imprimer des messages d'exception Python dans un fichier journal avec logging.error:

import logging
try:
    1/0
except ZeroDivisionError as e:
    logging.error(e)  # ERROR:root:division by zero

Est-il possible d'imprimer des informations plus détaillées sur l'exception et le code qui l'a générée que simplement la chaîne d'exception ? Des éléments tels que les numéros de ligne ou les traces d'appel seraient géniaux.

1117voto

SiggyF Points 5320

logger.exception affichera une trace de la pile en plus du message d'erreur.

Par exemple :

import logging
try:
    1/0
except ZeroDivisionError:
    logging.exception("message")

Sortie :

ERROR:root:message
Traceback (most recent call last):
  File "", line 2, in 
ZeroDivisionError: division par zéro

@Paulo Cheque remarque, "soyez conscient qu'en Python 3 vous devez appeler la méthode logging.exception juste à l'intérieur de la partie except. Si vous appelez cette méthode à un endroit arbitraire, vous pourriez obtenir une exception bizarre. Les docs mettent en garde à ce sujet."

213 votes

La méthode exception appelle simplement error(message, exc_info=1). Dès que vous passez exc_info à l'une des méthodes de journalisation à partir d'un contexte d'exception, vous obtiendrez une trace de la pile.

23 votes

Vous pouvez également définir sys.excepthook (voir ici) pour éviter d'avoir à envelopper tout votre code dans un bloc try/except.

26 votes

Vous pourriez simplement écrire except Exception: car vous n'utilisez pas du tout e ;)

215voto

ncoghlan Points 10779

Une chose agréable à propos de logging.exception que la réponse de SiggyF ne montre pas, c'est que vous pouvez passer un message arbitraire, et le journal affichera toujours la trace avec tous les détails de l'exception :

import logging
try:
    1/0
except ZeroDivisionError:
    logging.exception("Traceback délibéré en cas de division par zéro")

Avec le comportement de journalisation par défaut (dans les versions récentes) qui se contente d'afficher les erreurs sur sys.stderr, cela ressemble à ceci :

>>> import logging
>>> try:
...     1/0
... except ZeroDivisionError:
...     logging.exception("Traceback délibéré en cas de division par zéro")
... 
ERROR:root:Traceback délibéré en cas de division par zéro
Traceback (most recent call last):
  File "", line 2, in 
ZeroDivisionError: division entière ou modulo par zéro

0 votes

Le message d'erreur peut-il être enregistré sans fournir de message?

0 votes

@StevenVascellaro - Je vous suggère de passer '' si vous ne voulez vraiment pas taper de message... la fonction ne peut pas être appelée sans au moins un argument, donc vous devrez lui donner quelque chose.

0 votes

@ncoghlan pouvez-vous s'il vous plaît suggérer la solution pour la question suivante: stackoverflow.com/questions/68168756/…

4voto

winterTTr Points 1020

Les objets Traceback représentent une trace de pile d'une exception. Un objet Traceback est créé lorsqu'une exception se produit. Lorsque la recherche d'un gestionnaire d'exception déroule la pile d'exécution, à chaque niveau déroulé un objet Traceback est inséré devant le traceback actuel. Lorsqu'un gestionnaire d'exception est entré, la trace de la pile est rendue disponible au programme. (Voir la section L'instruction try.) Elle est accessible sous forme de sys.exc_traceback, et également en tant que troisième élément du tuple retourné par sys.exc_info(). Cette dernière est l'interface privilégiée, car elle fonctionne correctement lorsque le programme utilise plusieurs threads. Lorsque le programme ne contient aucun gestionnaire adapté, la trace de la pile est écrite (correctement formatée) vers le flux d'erreur standard; si l'interpréteur est interactif, elle est également mise à disposition de l'utilisateur sous forme de sys.last_traceback.

pour plus d'informations, consultez le site : http://docs.python.org/library/sys.html

-3voto

Jakob Bowyer Points 12873

Si vous pouvez gérer la dépendance supplémentaire, utilisez twisted.log, vous n'avez pas besoin de journaliser explicitement les erreurs et il renvoie également la trace complète et le temps dans le fichier ou le flux.

12 votes

Peut-être twisted est une bonne recommandation, mais cette réponse ne contribue pas vraiment beaucoup. Il ne dit pas comment utiliser twisted.log, ni quels avantages il a par rapport au module logging de la bibliothèque standard, ni n'explique ce qui est signifié par "vous n'avez pas à enregistrer explicitement les erreurs".

-10voto

caraconan Points 1

Une manière propre de le faire consiste à utiliser format_exc() et ensuite analyser la sortie pour obtenir la partie pertinente :

from traceback import format_exc

try:
    1/0
except Exception:
    print 'la partie pertinente est : '+format_exc().split('\n')[-2]

Cordialement

6 votes

Huh? Pourquoi est-ce que "la partie pertinente"? Tout ce que le .split('\n')[-2] fait est de jetter le numéro de ligne et la trace de la résultat de format_exc() - des informations utiles que vous voulez normalement! De plus, cela ne le fait même pas bien; si votre message d'exception contient un saut de ligne, alors cette approche ne fera imprimer que la dernière ligne du message d'exception - ce qui signifie que vous perdez la classe d'exception et la plupart du message d'exception en plus de perdre la trace. -1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X