2014-03-28 39 views
1

我有一個應用程序,它根據外部參數運行主應用程序的幾個實例。主應用程序導入很少的庫,然後導入其他庫。他們都有一個全球性的關於動態python日誌記錄的想法

LOGGER = logging.getLogger('module_name')

記錄器配置爲使所有的日誌被寫入到一個外部文件(所有日誌寫入到同一個文件)文件處理程序。現在我想根據傳遞給主應用程序的特定名稱將日誌寫入不同的文件。我需要一個像

LOGGER = logging.getLogger(dynamic_criteria_name)

結果有些事情將是多個日誌文件dynamic_criteria_name.log,dynamic_criteria_name.log等創建並隨時記錄器從任何一個模塊的把它稱爲寫信給基於正確的文件根據它被稱爲的標準。

但問題是LOGGER是全球性的。我可以將記錄器或dynamic_criteria_name傳遞給每個函數來寫入日誌,但它聽起來有些錯誤。可能是我只是偏執狂!我有一些模塊,有時只有它們的功能。我不想讓記錄器在我猜中繞過。

我曾經想過AOP一段時間,但我不認爲它是真正的交叉切割,因爲它是動態生成的,記錄器在我看來是橫切,但在主應用程序的一個實例中。我曾想過其他方法來攻擊全球國家,但我認爲動態的本質至少在我的腦海中是不可能的。

下面是僞代碼(我沒有嘗試過它運行它),但它更好地解釋我在說什麼,我想。正如你可以看到module_1導入module_2和module_3,它們都有一個全局LOGGER,module_3調用module_4。我想知道是否可以寫入module_2或module_3的單獨日誌文件,而不必將每個導入的模塊函數明確地傳遞給名稱。我可以使用不同的文件名向記錄器添加多個處理程序,但是如何從另一個模塊中引用正確的記錄器,因爲它們現在都是全局的。

# module_1.py 
import logging 
import time 

import module_2 
import module_3 

LOGGER = logging.getLogger() 


def start_main_loop(name): 
    while True: 
     module_2.say_boo() 
     module_3.say_foo() 
     LOGGER.debug('Sleeping...') 
     time.sleep(10) 

if __name__ == '__main__': 
    logging.basicConfig(level=logging.DEBUG) 
    for i in xrange(10): 
     start_main_loop(i) 

#----------------------------------------------------   
# module_2.py 

import logging 

LOGGER = logging.getLogger() 

def say_boo(): 
    msg = 'boo' 
    LOGGER.debug(msg) 
    LOGGER.debug(say_twice(msg)) 

def say_twice(msg): 
    LOGGER.debug('Called say twice') 
    return msg * 2 

#----------------------------------------------------  
# module_3.py 

import logging 

import module_4 

LOGGER = logging.getLogger() 

def say_foo(): 
    msg = 'foo' 
    LOGGER.debug(msg) 
    LOGGER.debug(say_twice(msg)) 
    module_4.say_bar() 

def say_twice(msg): 
    LOGGER.debug('Called say twice') 
    return msg * 2 

#----------------------------------------------------  
# module_4.py 

import logging 

LOGGER = logging.getLogger() 

def say_bar(): 
    msg = 'bar' 
    LOGGER.debug(msg) 

我願意探索任何想法的人可能有。希望我已經清楚地解釋了自己,如果不是,請讓我知道,我可以重述這個問題。謝謝!

+0

每個模塊都可以使用它的'__name__'作爲記錄器名稱。如果要將函數名稱添加到記錄器名稱中,則每個函數都具有'func_name'屬性。 – msvalkon

+0

對不起 - 我需要基於動態名稱的不同日誌文件。 – opensourcegeek

+0

您可以在記錄器中擁有任意數量的處理程序,這應該不成問題。 – msvalkon

回答

0

您不需要傳遞記錄器:記錄器是單身人士。如果多個模塊中的代碼調用getLogger('foo'),則每個調用都會返回相同的實例。所以不需要傳遞記錄器實例。一般來說,記錄器名稱指示日誌記錄調用的起始位置,因此__name__值最有意義。您可以將模塊foo中的代碼記錄到名爲bar的記錄器 - 沒有任何東西阻止您這樣做 - 它在實踐中沒有被發現特別有用。

聽起來像AOP是矯枉過正。根據您的特定要求,您可以考慮在根記錄器中添加多個處理程序,而不是在每個處理程序上添加特定的過濾器,以確保特定的東西進入特定的文件。

+0

我用一個例子更新了我的問題。如果你能用一些代碼解釋你的想法,那將是非常好的。我知道我可以添加多個處理程序(我使用RotatingFileHandler)記錄器,但我之前沒有使用過濾器。我努力得到的部分是,在我的例子中,如何根據給定的上下文(如'name')來擁有多個全局LOGGER實例。謝謝! – opensourcegeek