2009-06-19 4 views
6

Не могли бы вы помочь решить следующую проблему несовместимости между Python 2.5 и 2.6?Python logging incompatibilty между 2.5 и 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() 

Выход вызова logger.py под Ubuntu 9.04:

$ python2.5 logger.py 
$ 

$ python2.6 logger.py 
function_one() called. 
function_two() called. 
$ 

ответ

8

Это ошибка, которая была установлена ​​между 2.5 и 2.6. Функция fileConfig() предназначена для одноразовой конфигурации и поэтому не должна вызываться более одного раза - однако вы решили организовать это. Предполагаемое поведение fileConfig - отключить любые регистраторы, которые явно не указаны в конфигурации, и оставить включенным указанных регистраторов и их детей; ошибка приводила к тому, что дети были отключены, когда они не должны были быть. В примере конфигурации регистратора упоминаются журналы «a» и «b»; после вызова getLogger ('a.submod') создается дочерний регистратор. Второй вызов fileConfig неправильно отключает это в Python 2.5 - в Python 2.6 регистратор не отключен, так как он является дочерним элементом регистратора, явно упомянутого в конфигурации.

+0

Звучит довольно близко к правой. – Triptych

+0

Большое спасибо за подробное описание проблемы. – Szilveszter

+1

Triptych: Это должно быть правильно, потому что на него отвечает тот, кто поддерживает модуль регистрации python;) –

1

Я не понимаю причины такого поведения, но сам, как вы хорошо изложены в 2.6 он работает по-другому. Можно предположить, что это ошибка влияет на 2,5

В качестве обходного пути я предлагаю следующее:

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.") 

с помощью этой схемы мне удалось запустить logger.py на python2.5.4 с тем же поведением, что и у 2.6

+0

Спасибо за обходной путь, он действительно работает. – Szilveszter

0

Интересно ... Я немного поиграл в консоли, и похоже, что второй звонок logging.config.fileConfig - это ошибка вещи вверх. Не знаю, почему это, хотя ... Вот запись, которая показывает проблему:

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 
>>> 

Как только я называю logging.config.fileConfig во второй раз, мой экземпляр регистратор прекращает регистрацию. Захват нового экземпляра журнала не помогает, поскольку это тот же объект. Если я подожду до тех пор, пока не настроит оба раза для извлечения экземпляров журнала, все будет работать - вот почему работает экземпляр blog.

Мое предложение - отложить захват экземпляров регистратора до тех пор, пока вы не выполните функции. Если вы переместите звонки на logging.getLogger() в function_one и function_two, тогда все будет хорошо.

0

я был в состоянии исправить это, изменив имена лесорубов, как это так, в обоих файлах:

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

Я не уверен в точной ошибки, но модуль v2.5 регистратор, кажется, имеют проблемы с совпадающими именами, переданными в getLogger() с именами в файле конфигурации.

Смежные вопросы