288 votes

La journalisation Python ne donne rien en sortie

Dans un script python que j'écris, j'essaie d'enregistrer des événements à l'aide du module d'enregistrement. J'ai le code suivant pour configurer mon logger :

ERROR_FORMAT = "%(levelname)s at %(asctime)s in %(funcName)s in %(filename) at line %(lineno)d: %(message)s"
DEBUG_FORMAT = "%(lineno)d in %(filename)s at %(asctime)s: %(message)s"
LOG_CONFIG = {'version':1,
              'formatters':{'error':{'format':ERROR_FORMAT},
                            'debug':{'format':DEBUG_FORMAT}},
              'handlers':{'console':{'class':'logging.StreamHandler',
                                     'formatter':'debug',
                                     'level':logging.DEBUG},
                          'file':{'class':'logging.FileHandler',
                                  'filename':'/usr/local/logs/DatabaseUpdate.log',
                                  'formatter':'error',
                                  'level':logging.ERROR}},
              'root':{'handlers':('console', 'file')}}
logging.config.dictConfig(LOG_CONFIG)

Quand j'essaie d'exécuter logging.debug("Some string") je n'obtiens aucune sortie sur la console, même si cette page dans les docs dit que logging.debug devrait faire en sorte que le journal de bord Root affiche le message. Pourquoi mon programme ne produit-il rien, et comment puis-je y remédier ?

383voto

Hubert Grzeskowiak Points 5836

Plusieurs années plus tard, il semble qu'il y ait toujours un problème de convivialité avec le logger Python. Voici quelques explications accompagnées d'exemples :

import logging
# This sets the root logger to write to stdout (your console).
# Your script/app needs to call this somewhere at least once.
logging.basicConfig()

# By default the root logger is set to WARNING and all loggers you define
# inherit that value. Here we set the root logger to NOTSET. This logging
# level is automatically inherited by all existing and new sub-loggers
# that do not set a less verbose level.
logging.root.setLevel(logging.NOTSET)

# The following line sets the root logger level as well.
# It's equivalent to both previous statements combined:
logging.basicConfig(level=logging.NOTSET)

# You can either share the `logger` object between all your files or the
# name handle (here `my-app`) and call `logging.getLogger` with it.
# The result is the same.
handle = "my-app"
logger1 = logging.getLogger(handle)
logger2 = logging.getLogger(handle)
# logger1 and logger2 point to the same object:
# (logger1 is logger2) == True

logger = logging.getLogger("my-app")
# Convenient methods in order of verbosity from highest to lowest
logger.debug("this will get printed")
logger.info("this will get printed")
logger.warning("this will get printed")
logger.error("this will get printed")
logger.critical("this will get printed")

# In large applications where you would like more control over the logging,
# create sub-loggers from your main application logger.
component_logger = logger.getChild("component-a")
component_logger.info("this will get printed with the prefix `my-app.component-a`")

# If you wish to control the logging levels, you can set the level anywhere 
# in the hierarchy:
#
# - root
#   - my-app
#     - component-a
#

# Example for development:
logger.setLevel(logging.DEBUG)

# If that prints too much, enable debug printing only for your component:
component_logger.setLevel(logging.DEBUG)

# For production you rather want:
logger.setLevel(logging.WARNING)

Une source fréquente de confusion provient d'un enregistreur Root mal initialisé. Considérez ceci :

import logging
log = logging.getLogger("myapp")
log.warning("woot")
logging.basicConfig()
log.warning("woot")

Sortie :

woot
WARNING:myapp:woot

En fonction de votre environnement d'exécution et des niveaux de journalisation, la première ligne du journal (avant la configuration de base) peut n'apparaître nulle part. .

198voto

Omri Barel Points 4426

Le niveau de journalisation par défaut est l'avertissement. Puisque vous n'avez pas modifié le niveau, le niveau de journalisation de Root est toujours warning. Cela signifie qu'il ignorera toute journalisation dont le niveau est inférieur à warning, y compris les journalisations de débogage.

Ceci est expliqué dans le tutoriel :

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

La ligne 'info' n'imprime rien, car le niveau est supérieur à info.

Pour modifier le niveau, il suffit de le définir dans le logger Root :

'root':{'handlers':('console', 'file'), 'level':'DEBUG'}

En d'autres termes, il ne suffit pas de définir un gestionnaire avec level=DEBUG, le niveau d'enregistrement réel doit également être DEBUG pour qu'il produise quelque chose.

145voto

neuronet Points 316

Pour tous ceux ici qui veulent une réponse super-simple : il suffit de définir le niveau que vous voulez afficher. En haut de tous mes scripts je mets juste :

import logging
logging.basicConfig(level = logging.INFO)

Puis d'afficher tout ce qui se trouve à ce niveau ou au-dessus :

logging.info("Hi you just set your fleeb to level plumbus")

Il s'agit d'un ensemble hiérarchique de cinq niveaux, de sorte que les journaux s'affichent au niveau que vous avez défini, soit plus haut . Donc, si vous voulez afficher une erreur, vous pouvez utiliser logging.error("The plumbus is broken") .

Les niveaux, par ordre croissant de gravité, sont les suivants DEBUG , INFO , WARNING , ERROR y CRITICAL . Le paramètre par défaut est WARNING .

Voici un bon article contenant ces informations exprimées mieux que ma réponse :
https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3

26voto

yue dong Points 409

Essayez peut-être ceci ? Il semble que le problème soit résolu après avoir supprimé tous les handlers dans mon cas.

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

logging.basicConfig(filename='output.log', level=logging.INFO)

6voto

Cjo Points 419

import logging
log = logging.getLogger()
log.setLevel(logging.DEBUG)

ce code définira le niveau de journalisation par défaut à DEBUG.

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