你能帮我解决Python 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()
在Ubuntu 9.04下调用logger.py的输出:
$ python2.5 logger.py
$
$ python2.6 logger.py
function_one() called.
function_two() called.
$
答案 0 :(得分:8)
这是一个在2.5和2.6之间修复的错误。 fileConfig()函数用于一次性配置,因此不应多次调用 - 但是您选择安排它。 fileConfig的预期行为是禁用配置中未明确提及的任何记录器,并保留启用提到的记录器及其子项;这个错误导致孩子们不应该被禁用。示例记录器配置提到记录器'a'和'b';在调用getLogger('a.submod')之后,会创建一个子记录器。第二个fileConfig调用在Python 2.5中错误地禁用了它 - 在Python 2.6中,记录器没有被禁用,因为它是配置中明确提到的记录器的子代。
答案 1 :(得分: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.")
通过使用这个方案,我能够在python2.5.4上运行logger.py,其行为与2.6相同
答案 2 :(得分: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
,那么一切正常。
答案 3 :(得分:0)
我能够通过在两个文件中更改记录器的名称来解决这个问题:
logging.config.fileConfig('logger.conf')
a_log = logging.getLogger('a')
b_log = logging.getLogger('b')
我不确定确切的错误,但是v2.5记录器模块似乎无法将传递给getLogger()
的名称与配置文件中的名称进行匹配。