Comment provoquer la sortie d'exceptions non interceptées via le logging
module plutôt que vers stderr
?
Je réalise que la meilleure façon de procéder serait:
try:
raise Exception, 'Throwing a boring exception'
except Exception, e:
logging.exception(e)
Mais ma situation est telle que ce serait vraiment bien si elles logging.exception(...)
étaient invoquées automatiquement chaque fois qu'une exception n'est pas interceptée.
python
logging
exception-handling
Marbre Jacob
la source
la source
Réponses:
Comme Ned l'a souligné,
sys.excepthook
est invoquée chaque fois qu'une exception est levée et non interceptée. L'implication pratique de ceci est que dans votre code, vous pouvez remplacer le comportement par défaut desys.excepthook
pour faire ce que vous voulez (y compris en utilisantlogging.exception
).Comme exemple d'homme de paille:
Remplacer
sys.excepthook
:Validez une erreur de syntaxe évidente (laissez de côté les deux points) et récupérez les informations d'erreur personnalisées:
Pour plus d'informations sur
sys.excepthook
, lisez la documentation .la source
type
comme argument de fonction, bien que les IDE se plaignent de cacher le globaltype
(un peu comme l'utilisationvar self = this
en Javascript). Cela n'a pas vraiment d'importance à moins que vous n'ayez besoin d'accéder à l'type
objet dans votre fonction, auquel cas vous pouvez l'utilisertype_
comme argument à la place.sys.excepthook
n'est PAS appelé lorsqu'une exception est "déclenchée". Il est appelé lorsque le programme va se terminer en raison d'une exception non interceptée, ce qui ne peut pas se produire plus d'une fois.Voici un petit exemple complet qui comprend également quelques autres astuces:
Ignorez KeyboardInterrupt pour qu'un programme python de console puisse quitter avec Ctrl + C.
Fiez-vous entièrement au module de journalisation de python pour formater l'exception.
Utilisez un enregistreur personnalisé avec un exemple de gestionnaire. Celui-ci modifie l'exception non gérée pour aller à stdout plutôt qu'à stderr, mais vous pouvez ajouter toutes sortes de gestionnaires dans ce même style à l'objet logger.
la source
logger.critical()
à l'intérieur du gestionnaire excepthook, car une exception non interceptée est assez critique je dirais.logging.basicConfig(level=logging.DEBUG, filename="debug.log", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mais n'a pas aidé.La méthode
sys.excepthook
sera appelée si une exception n'est pas interceptée: http://docs.python.org/library/sys.html#sys.excepthookla source
type
l'instance?sys.excepthook
?Pourquoi pas:
Voici la sortie avec
sys.excepthook
comme vu ci-dessus:Voici la sortie avec le
sys.excepthook
commentaire:La seule différence est que le premier a
ERROR:root:Unhandled exception:
au début de la première ligne.la source
sys.stderr
.Pour construire sur la réponse de Jacinda, mais en utilisant un objet logger:
la source
functools.partial()
au lieu de lambda. Voir: docs.python.org/2/library/functools.html#functools.partialEnveloppez votre appel d'entrée d'application dans un
try...except
bloc afin que vous puissiez attraper et enregistrer (et peut-être relancer) toutes les exceptions non interceptées. Par exemple au lieu de:Faites ceci:
la source
Vous pourriez peut-être faire quelque chose en haut d'un module qui redirige stderr vers un fichier, puis consigner ce fichier en bas
la source
Bien que la réponse de @ gnu_lorien m'ait donné un bon point de départ, mon programme plante à la première exception.
Je suis venu avec une solution personnalisée (et / ou) améliorée, qui enregistre silencieusement les exceptions des fonctions qui sont décorées
@handle_error
.la source
Pour répondre à la question de Mr.Zeus discutée dans la section commentaire de la réponse acceptée, j'utilise ceci pour enregistrer les exceptions non détectées dans une console interactive (testée avec PyCharm 2018-2019). J'ai découvert que
sys.excepthook
cela ne fonctionnait pas dans un shell python, alors j'ai regardé plus profondément et j'ai trouvé que je pourrais l'utiliser à lasys.exc_info
place. Cependant,sys.exc_info
ne prend aucun argument contrairement àsys.excepthook
cela prend 3 arguments.Ici, j'utilise les deux
sys.excepthook
etsys.exc_info
pour enregistrer les deux exceptions dans une console interactive et un script avec une fonction wrapper. Pour attacher une fonction hook aux deux fonctions, j'ai deux interfaces différentes selon que des arguments sont donnés ou non.Voici le code:
La configuration de la journalisation peut être trouvée dans la réponse de gnu_lorien.
la source
Dans mon cas (en utilisant
python 3
) lors de l'utilisation de la réponse de @Jacinda, le contenu du retraçage n'a pas été imprimé. Au lieu de cela, il imprime juste l'objet lui - même:<traceback object at 0x7f90299b7b90>
.Au lieu de cela, je fais:
la source