Несовместимость ведения журнала Python между 2.5 и 2.6

StackOverflow https://stackoverflow.com/questions/1018527

  •  06-07-2019
  •  | 
  •  

Вопрос

Не могли бы вы помочь мне решить следующую проблему несовместимости между Python 2.5 и 2.6?

logger.conf регистратор.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.
$
Это было полезно?

Решение

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

Другие советы

Я сам не понимаю причин такого поведения, но, как вы хорошо указали в 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

Интересно...Я немного поиграл в консоли, и это похоже на второй вызов 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 во второй раз мой экземпляр logger прекращает ведение журнала.Захват нового экземпляра журнала не помогает, поскольку это один и тот же объект.Если я подожду, пока после настройки оба раза не будут извлечены экземпляры регистратора, тогда все заработает - вот почему blog экземпляр работает.

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

Я смог исправить это, изменив имена регистраторов следующим образом в обоих файлах:

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top