簡體   English   中英

Python記錄多個模塊記錄器不在主程序外工作

[英]Python logging multiple modules logger not working outside main program

我的目標是從多個模塊進行日志記錄,而只在一個地方配置記錄器 - 在主程序中。 這個答案所示,應該包括

logging.config.fileConfig('/path/to/logging.conf') 

在主程序中,然后在所有其他模塊中包括

logger = logging.getLogger(__name__)

我相信這就是我在下面所做的,但我得到了意想不到的行為。

c.py

# c.py
import logging
import logging.config
import d

logging.config.fileConfig("logging.conf")
logger = logging.getLogger(__name__)

logger.warning('logging from c')
d.foo()

d.py

# d.py
import logging

logger = logging.getLogger(__name__)

# this will print when d is imported
logger.warning('logging from d on import')

def foo():
    # this does not print
    logger.warning("logging from d on call foo()")

產量

$ python c.py
logging from d on import
logging from c

我期望的是,當d.foo()c.py執行時,將從d記錄消息,但事實並非如此。 這很令人困惑,因為當從d模塊級別調用記錄器時,它會將一條消息記錄到控制台,但是當從foo()內部調用時它不會。

配置文件

[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(message)s
datefmt=

更深入的分析

所以我注意到,如果我刪除該行

logging.config.fileConfig("logging.conf")

c.py ,然后從d.foo()進行日志記錄按預期工作。 所以在配置文件中有錯誤或由於我提供配置文件導致d.py的記錄器搞砸了。

  1. 為什么從模塊級別調用時會從d記錄消息,而不是從d.foo()內部d.foo()
  2. 如何才能實現從多個模塊進行日志記錄的目標,同時僅在主程序中配置日志記錄?

問題在於這樣一個事實

import d

來之前

logging.config.fileConfig("logging.conf")

正如@davidejones所指出的那樣。 原因如下:

文檔中所述,當調用logging.config.fileConfig()時,其默認行為是禁用任何現有記錄器。 因此,當import d發生時, loggerd初始化,然后當調用logging.config.fileConfig()時, dlogger被禁用,這就是為什么我們在調用d.foo()時沒有看到任何記錄。

logging.config.fileConfig()接受一個參數disable_existing_loggers ,默認為True 使用

logging.config.fileConfig("logging.conf", disable_existing_loggers=False)

輸出變成了

>>> python c.py
logging from d on import
logging from c
logging from d on call foo()

正如所料。

我認為d的導入是在記錄器的配置之前發生的,所以做這樣的事情可能會給你想要的東西?

# c.py
import logging
import logging.config

logging.config.fileConfig("logging.conf")
logger = logging.getLogger(__name__)

import d


logger.warning('logging from c')
d.foo()

它給了我這些結果

logging from d on import
logging from c
logging from d on call foo()

編輯

查看代碼可能更有意義的是讓一個單獨的文件進行日志記錄設置,然后在主文件中導入一次,其他模塊將擁有它然后它看起來並不那么混亂。 所以可能有像這樣的logsetup.py

import logging
import logging.config

logging.config.fileConfig("logging.conf")

然后c.py看起來像這樣,但仍然給出相同的結果

# c.py
import logsetup
import logging
import d

logger = logging.getLogger(__name__)

logger.warning('logging from c')
d.foo()

暫無
暫無

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

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