Python日志记录在2.5和2.6之间不兼容

时间:2009-06-19 15:14:15

标签: python logging incompatibility

你能帮我解决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.
$

4 个答案:

答案 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_onefunction_two,那么一切正常。

答案 3 :(得分:0)

我能够通过在两个文件中更改记录器的名称来解决这个问题:

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

我不确定确切的错误,但是v2.5记录器模块似乎无法将传递给getLogger()的名称与配置文件中的名称进行匹配。