2014-10-16 152 views
3

我想在我的Python庫模塊中設置通用日誌記錄,以便它們使用調用模塊中配置的日誌記錄器而不必硬編碼記錄器名稱。我在調用模塊中看到了很多使用logging.basicConfig()的示例,並在庫模塊中調用logging.debug(),但在配置我自己的StreamHandler時不起作用。我究竟做錯了什麼?從庫模塊的Python日誌記錄

這是我的電話模塊:

import logging, logging.handlers 
logger = logging.getLogger(__name__) 
logger.setLevel(logging.INFO) 
consolehandler = logging.StreamHandler() 
consoleformatter = logging.Formatter('[%(name)s] %(levelname)s %(message)s') 
consolehandler.setFormatter(consoleformatter) 
logger.addHandler(consolehandler) 
import libmodule 

def run(): 
    logger.info("message from calling module") 
    libmodule.say("message from library module") 

我在libmodule.py試過這樣:

import logging 

def say(msg): 
    logging.info(msg) 

這:

import logging 
logger = logging.getLogger() 

def say(msg): 
    logger.info(msg) 

但在這兩種情況下,當我調用運行(),我得到這個輸出:

[callingmodule] INFO message from calling module 

但期待這樣的:

[callingmodule] INFO message from calling module 
[callingmodule] INFO message from library module 

回答

2

這是因爲在一審中,您可以通過名字得到一個記錄器,並在第二,你只需要使用getLogger(),它返回根記錄。哪個不是同一個,並且沒有安裝您的自定義流處理程序。

的更簡單的方式做,這是遵循文檔here指導:

「多次調用getLogger()具有相同的名稱將始終返回 參照同Logger對象。」

換句話說,如果你只是在這兩個地方使用getLogger('my_common_name'),然後他們兩個會自動指向同一個記錄器,即使你在一個地方定製它。

補充:如果你想捕捉從父記錄器,那麼你會做這樣的事情在你的庫:

# In libmodule 

_log = None 

def initLogger(logger=None): 
    global _log 
    if logger != None: 
     _log = logger 
    else: 
     import logging 
     _log = logging.getLogger() 

# Later in the module 
def say(message): 
    _log.info(message) 
父模塊中

則:

# In the parent module 
mylog = a logger i set up 

import libmodule 
libmodule.initLogger(mylog) 

應使他們都指向同一個記錄器。

+0

感謝您回覆Corley。這將意味着硬編碼我的庫代碼中的通用名稱,並且只會在庫的用戶選擇相同的通用名稱時才起作用。 – 2014-10-16 15:12:15

+1

好吧,你現在正在這樣做,有點(都在查看中央日誌記錄模塊並尋找硬代碼記錄器,一個是'__file__',另一個是根目錄;兩者都不直視對方)。你是否試圖允許用戶將圖書館記錄器重新路由到他們自己的?做這件事的標準方法是,有一個'initLogger()'函數來初始化庫記錄器,你可以傳入一個記錄器。如果沒有記錄器通過,它創建它自己的。類似的東西。 – 2014-10-16 15:34:25

+0

你說得對,我想把圖書館記錄器重新路由到用戶配置的記錄器中,但我希望能自動完成。 'initLogger()'方法聽起來很有趣。有沒有可以指點我的例子? – 2014-10-16 15:46:39

相關問題