2010-07-28 75 views
10

我有一個包含多個組件的包,它將從使用日誌記錄和輸出有用信息中受益匪淺。在包模塊中設置日誌記錄的有效方法

我不想做的是「設置」適當的日誌記錄與沿着這些線路的地方的每一個文件:

import logging 
logging.basicConfig(level=DEBUG) 
my_function = logging.getLogger("my_function") 
my_class = logging.getLogger("my_class") 

我已經嘗試了幾個方法,其中之一是將樣板碼到公用模塊中的類,並嘗試做這樣的事情:

from util import setlogging 
set_logging() 

但是,即使上述方案看起來不乾淨的給我,並會造成問題,因爲setLogger沒有一個__call__方法。我所喜歡的是,我的「set_logging」類將從配置文件中讀取,並具有一些默認值,因此無論什麼級別或我想要的記錄格式類型都可以正確設置。

有沒有辦法在我的軟件包中初始化全面的日誌?也許在__init__.py文件中?

而只是爲了儘可能詳細,這是setlogging(現在是一個函數,不是類)看起來像:

def setlogging(config=None): 
    if config == None: 
     config = config_options() # sets default values 
    levels = { 
     'debug': DEBUG, 
     'info': INFO 
     } 

    level = levels.get(config['log_level']) 
    log_format = config['log_format'] 
    datefmt = config['log_datefmt'] 

    basicConfig(
     level = level, 
     format = log_format, 
     datefmt = datefmt) 

回答

11

如果你想在你的包中各個模塊的所有代碼使用相同的Logger對象,你只需要(使該記錄器可用 - 見下文 - 和)調用

mylogger.warning("Attenzione!") 

或類似的,而不是logging.warning &℃。所以,這個問題可以簡化爲爲整個包製作一個mylogger對象,並使其在包中的所有模塊中都可用。 (或者,您可以使用命名記錄器,名稱以包名後跟一個點開頭,但雖然這是包裝功能的一部分,但我個人從未發現它是一種自然的操作方式)。

所以,你util.setlogging功能可以簡單地之後,也就是說,

mylogger = logging.getLogger(package_name) 

和每一個進口util可以簡單地使用

util.mylogger.warning('Watch out!') 

等的模塊。在我看來,這似乎是最簡單的方法,只要包中的所有代碼都應該以相同的方式登錄即可。

+0

我是否仍然需要調用setlogging()才能訪問「mylogger」?儘管我嘗試這樣做,但由於'function'對象沒有'mylogger'屬性,我仍然得到了預期的AttributeError。 也許我沒有完全明白... – alfredodeza 2010-07-28 00:55:16

+0

@alfredo,它只需要調用一次(從包的'__init __。py'將是最簡單的用途,因爲你知道它總是在包中的任何模塊中的任何代碼之前運行),當然您可以在該記錄器中添加一個處理程序,並根據您的需要配置其格式程序,如http://docs.python.org/library/logging.html?highlight=logging#configuring-logging中給出的示例代碼。 – 2010-07-28 00:56:49

+0

謝謝亞歷克斯,真的幫了大忙!明年我會在PyCon爲你買一瓶啤酒:) – alfredodeza 2010-07-28 01:02:44

1

一個模塊來使用記錄的正確方法是

import logging 
logger = logging.getLogger('my_module_name') 

logger.debug('help!') 

變成了無操作,直到有人叫logging.basicConfig()(或變體)。