簡體   English   中英

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"

我也有一個使用my_mod.my_command的python腳本my_script.py 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的print語句成功打印到控制台:

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

我究竟做錯了什么?

注意:該示例顯示使用調試,但是即使當我繼續為根LOGGER.info(message)記錄器指定logging.cfg指定level=DEBUG (我也嘗試了level=NOTSET )並在my_command調用LOGGER.info(message)時,也沒有任何內容記錄到控制台。

潛在的問題是在設置記錄器配置之前,您正在導入模塊。 這樣,模塊將在設置日志記錄之前請求記錄器。

查看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的默認值是這樣...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM