Question

Pourriez-vous m'aider à résoudre le problème d'incompatibilité suivant entre Python 2.5 et 2.6?

logger.conf:

[loggers]
keys=root,aLogger,bLogger

[handlers]
keys=consoleHandler

[formatters]
keys=

[logger_root]
level=NOTSET
handlers=consoleHandler

[logger_aLogger]
level=DEBUG
handlers=consoleHandler
propagate=0
qualname=a

[logger_bLogger]
level=INFO
handlers=consoleHandler
propagate=0
qualname=b

[handler_consoleHandler]
class=StreamHandler
args=(sys.stderr,)

module_one.py:

import logging
import logging.config

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a.submod')
b_log = logging.getLogger('b.submod')

def function_one():
    b_log.info("function_one() called.")

module_two.py:

import logging
import logging.config

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a.submod')
b_log = logging.getLogger('b.submod')

def function_two():
    a_log.info("function_two() called.")

logger.py:

from module_one import function_one
from module_two import function_two

function_one()
function_two()

Sortie de l'appel logger.py sous Ubuntu 9.04:

$ python2.5 logger.py
$

$ python2.6 logger.py
function_one() called.
function_two() called.
$
Était-ce utile?

La solution

Ceci est un bug qui a été corrigé entre 2.5 et 2.6. La fonction fileConfig () est destinée à une configuration unique et ne doit donc pas être appelée plus d'une fois - quelle que soit l'option choisie. Le comportement souhaité de fileConfig est de désactiver tous les enregistreurs qui ne sont pas explicitement mentionnés dans la configuration et de laisser activés les enregistreurs mentionnés et leurs enfants. le bogue causait la désactivation des enfants alors qu'ils n'auraient pas dû l'être. L'exemple de configuration d'enregistreur mentionne les enregistreurs 'a' et 'b'; après avoir appelé getLogger ('a.submod'), un enregistreur enfant est créé. Le deuxième appel fileConfig le désactive à tort dans Python 2.5 - dans Python 2.6, le consignateur n’est pas désactivé car il s’agit d’un enfant d’un consignateur explicitement mentionné dans la configuration.

Autres conseils

Je ne comprends pas moi-même les raisons de ce comportement mais, comme vous l'avez bien dit dans la version 2.6, cela fonctionne différemment. Nous pouvons supposer qu’il s’agit d’un bogue affectant la version 2.5

Comme solution de contournement, je suggère ce qui suit:

extra_module.py:

import logging
import logging.config

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a.submod')
b_log = logging.getLogger('b.submod')

module_one.py:

from extra_module import a_log

def function_one():
    a_log.info("function_one() called.")

module_two.py:

from extra_module import b_log

def function_two():
    b_log.info("function_two() called.")

en utilisant ce schéma, j’ai pu exécuter logger.py sur python2.5.4 avec le même comportement que celui de 2.6

Intéressant ... J'ai un peu joué dans la console et il semble que le deuxième appel à logging.config.fileConfig est en train de tout gâcher. Vous n'êtes pas sûr de savoir pourquoi? Cependant, voici une transcription qui montre le problème:

lorien$ python2.5
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> import logging.config
>>> logging.config.fileConfig('logger.conf')
>>> alog = logging.getLogger('a.submod')
>>> alog.info('foo')
foo
>>> import logging
>>> import logging.config
>>> alog.info('foo')
foo
>>> logging.config.fileConfig('logger.conf')
>>> alog.info('foo')
>>> alog = logging.getLogger('a.submod')
>>> alog.info('foo')
>>> 
>>> blog = logging.getLogger('b.submod')
>>> blog.info('foo')
foo
>>>

Dès que j'appelle logging.config.fileConfig la deuxième fois, mon instance de consignateur arrête la journalisation. Saisir une nouvelle instance de journalisation n'aide pas, puisqu'il s'agit du même objet. Si j'attends qu'après avoir configuré les deux fois pour récupérer les instances de consignateur, tout fonctionne - c'est pourquoi l'instance blog fonctionne.

Ma suggestion est de retarder la récupération des instances de l'enregistreur jusqu'à ce que vous soyez dans les fonctions. Si vous déplacez les appels vers logging.getLogger () dans function_one et function_two , tout se passe bien.

J'ai pu résoudre ce problème en changeant les noms des enregistreurs comme suit, dans les deux fichiers:

logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a')
b_log = logging.getLogger('b')

Je ne suis pas sûr de l'erreur exacte, mais le module de journalisation v2.5 semble avoir du mal à faire correspondre les noms transmis à getLogger () avec des noms dans le fichier de configuration.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top