Python 根记录器消息未通过使用 fileConfig 配置的处理程序记录
Python root logger messages not being logged via handler configured with fileConfig
问题:
给定一个日志记录配置和一个使用该配置的记录器,我看到来自配置日志处理程序的脚本的日志消息,而不是来自分配了相同处理程序的根记录器的日志消息。
详情:
(使用 Python 2.7)
我有一个模块 my_mod
可以实例化一个记录器。 my_mod
有一个函数 my_command
,它使用该记录器记录一些消息。 my_mod
存在于库 my_lib
中,所以我不想使用任何处理程序配置记录器;按照建议,我想使用 my_mod
将日志处理留给开发人员。 my_mod
看起来像:
import logging
LOGGER = logging.getLogger(__name__)
def my_command():
LOGGER.debug("This is a log message from module.py")
print "This is a print statement from module.py"
我还有一个 python 脚本 my_script.py
,它使用 my_mod.my_command
。 my_script.py
实例化一个记录器,在这种情况下,我确实配置了处理程序和格式化程序。 my_script.py
使用 fileConfig
和与 my_script.py
:
并存的配置文件配置处理程序和格式化程序
import os
import logging
import logging.config
from my_mod.module import my_command
logging.config.fileConfig('{0}/logging.cfg'.format(
os.path.dirname(os.path.realpath(__file__))))
LOGGER = logging.getLogger(__name__)
LOGGER.debug("This is a log message from script.py")
my_command()
据我所知,我的配置文件似乎设置正确...
[loggers]
keys=root,script
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_script]
level=DEBUG
handlers=consoleHandler
qualname=script
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s [%(levelname)s] %(name)s: %(message)s
datefmt=
...但是当我 运行 my_script.py
时,我只得到来自 my_script.py
的日志行,而不是来自 my_mod.my_command
的日志行。不过,我知道 my_command
正在工作,因为调试日志语句成功打印到控制台后 my_command
中的打印语句:
20:27 $ python script.py
2015-06-15 20:27:54,488 [DEBUG] __main__: This is a log message from script.py
This is a print statement from module.py
我做错了什么?
注意:该示例显示使用调试,但即使我保持 logging.cfg 为根记录器指定 level=DEBUG
(我也尝试 level=NOTSET
)并在中调用 LOGGER.info(message)
my_command
,没有任何内容记录到控制台。
一个潜在的问题是您在设置记录器配置之前导入模块。这样,模块在设置日志记录之前请求一个记录器。
查看 fileConfig()
的文档,后续记录到预先获得的记录器失败的原因是其 disable_existing_loggers
参数的默认值:
logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)
如果您将代码更改为
logging.config.fileConfig(
'{0}/logging.cfg'.format(os.path.dirname(os.path.realpath(__file__))),
disable_existing_loggers=False
)
问题应该会消失。
请注意,现有记录器只有在配置文件中未明确命名时才会被禁用。例如:
import logging
import logging.config
lFooBefore = logging.getLogger('foo')
lScriptBefore = logging.getLogger('script')
logging.config.fileConfig('logger.ini')
lFooBefore.debug('Does not log')
lScriptBefore.debug('Does log')
logging.getLogger('foo').debug('Does also not log')
logging.getLogger('bar').debug('Does log')
不知道为什么 disable_existing_loggers
的默认值是这样的...
问题:
给定一个日志记录配置和一个使用该配置的记录器,我看到来自配置日志处理程序的脚本的日志消息,而不是来自分配了相同处理程序的根记录器的日志消息。
详情:
(使用 Python 2.7)
我有一个模块 my_mod
可以实例化一个记录器。 my_mod
有一个函数 my_command
,它使用该记录器记录一些消息。 my_mod
存在于库 my_lib
中,所以我不想使用任何处理程序配置记录器;按照建议,我想使用 my_mod
将日志处理留给开发人员。 my_mod
看起来像:
import logging
LOGGER = logging.getLogger(__name__)
def my_command():
LOGGER.debug("This is a log message from module.py")
print "This is a print statement from module.py"
我还有一个 python 脚本 my_script.py
,它使用 my_mod.my_command
。 my_script.py
实例化一个记录器,在这种情况下,我确实配置了处理程序和格式化程序。 my_script.py
使用 fileConfig
和与 my_script.py
:
import os
import logging
import logging.config
from my_mod.module import my_command
logging.config.fileConfig('{0}/logging.cfg'.format(
os.path.dirname(os.path.realpath(__file__))))
LOGGER = logging.getLogger(__name__)
LOGGER.debug("This is a log message from script.py")
my_command()
据我所知,我的配置文件似乎设置正确...
[loggers]
keys=root,script
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_script]
level=DEBUG
handlers=consoleHandler
qualname=script
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s [%(levelname)s] %(name)s: %(message)s
datefmt=
...但是当我 运行 my_script.py
时,我只得到来自 my_script.py
的日志行,而不是来自 my_mod.my_command
的日志行。不过,我知道 my_command
正在工作,因为调试日志语句成功打印到控制台后 my_command
中的打印语句:
20:27 $ python script.py
2015-06-15 20:27:54,488 [DEBUG] __main__: This is a log message from script.py
This is a print statement from module.py
我做错了什么?
注意:该示例显示使用调试,但即使我保持 logging.cfg 为根记录器指定 level=DEBUG
(我也尝试 level=NOTSET
)并在中调用 LOGGER.info(message)
my_command
,没有任何内容记录到控制台。
一个潜在的问题是您在设置记录器配置之前导入模块。这样,模块在设置日志记录之前请求一个记录器。
查看 fileConfig()
的文档,后续记录到预先获得的记录器失败的原因是其 disable_existing_loggers
参数的默认值:
logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)
如果您将代码更改为
logging.config.fileConfig(
'{0}/logging.cfg'.format(os.path.dirname(os.path.realpath(__file__))),
disable_existing_loggers=False
)
问题应该会消失。
请注意,现有记录器只有在配置文件中未明确命名时才会被禁用。例如:
import logging
import logging.config
lFooBefore = logging.getLogger('foo')
lScriptBefore = logging.getLogger('script')
logging.config.fileConfig('logger.ini')
lFooBefore.debug('Does not log')
lScriptBefore.debug('Does log')
logging.getLogger('foo').debug('Does also not log')
logging.getLogger('bar').debug('Does log')
不知道为什么 disable_existing_loggers
的默认值是这样的...