web-dev-qa-db-fra.com

Comment enregistrer le nom du fichier source et le numéro de ligne dans Python

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 ?

94
digy

Bien sûr, vérifiez formateurs dans les documents de journalisation. Plus précisément les variables lineno et pathname.

% (nom de chemin) s Nom de chemin complet du fichier source où l'appel de journalisation a été émis (si disponible).

% (nom de fichier) s Partie du nom de fichier du chemin d'accès.

% (module) s Module (partie nom du nom de fichier).

% (funcName) s Nom de la fonction contenant l'appel de journalisation.

% (lineno) d Numéro de la ligne source où l'appel de journalisation a été émis (si disponible).

Ressemble à ceci:

formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')
179
Seb

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 python
import 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] This is a debug log
2017-06-06:17:07:02,158 INFO     [log.py:12] This is an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13] This is critical
2017-06-06:17:07:02,158 ERROR    [log.py:14] An error occurred
56
codeforester

Pour construire sur ce qui précède d'une manière qui envoie la journalisation du 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.py Produit 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é cela une bien meilleure façon de le faire que d'utiliser des instructions print(). Où cela vous permet de désactiver la sortie de débogage en un seul endroit avant de la soumettre.

1
orangepips