2014-09-28 30 views
3

例如,我有這個文件與我想使用類(唯纔是舉,也許不工作)如何爲每個線程創建自己的日誌記錄實例?

# helper_one.py 

import logging 

logger = logging.getLogger('HelperOne') 

class HelperOne: 
    def __init__(self, data): 
     self.data = data 

    def run(self): 
     logger.debug('HelperOne::Run function with data: ' + self.data) 
     return True 

# controller_one.py 

import logging 

from helper_one import HelperOne 

logger = logging.getLogger('ControllerOne') 

class ControllerOne: 
    def __init__(self, data): 
     self.data = data 

    def run(self): 
     logger.debug('ControllerOne::Run function with data: ' + self.data) 

     ho = HelperOne(self.data + '_data') 
     return ho.run() 

,我有誰創建線程

import logging 

from controller_one import ControllerOne 

# this function create thread (its just example) 
def run_task(task_id, data): 
    logging.basicConfig(
     filename=os.path.join('logs', str(task_id) + '.log'), 
     level=logging.DEBUG, 
     format='%(asctime)s\t%(name)s\t%(levelname)s\t%(message)s' 
    ) 

    result = ControllerOne(data) 

    logging.debug('run_task: ' + result) 

如果我創建日誌例如像例子中的文件,所有日誌在一個文件中寫入。 我怎麼可以爲每個線程創建自己的日誌記錄實例與日誌記錄到自己的文件?

問候,亞歷克斯。

+0

我在python中不是很好,但是如果記錄器只能靜態地設置(即每個進程有1個實例),那麼就嘗試使用單獨的子進程而不是線程。 – Kam 2014-09-28 20:26:19

+0

@Kam,是的,我可以做到,但在我的情況下,這是不可能的。 – 2014-09-28 20:58:36

回答

3

記錄器名稱(傳遞給getLogger函數的字符串)可以是任何你想要的。作爲the docs解釋:

name的潛在的時段分隔的層次值,像foo.bar.baz(儘管它也可以是隻是普通foo,例如)。在分層列表中更靠後的記錄器是列表中較高記錄器的子記錄器。例如,給定一個名稱爲foo的記錄器,名稱爲foo.bar,foo.bar.bazfoo.bam的記錄器都是foo的後代。記錄器名稱層次結構類似於Python包層次結構,如果使用建議的構造logging.getLogger(__name__)以模塊爲單位組織記錄器,則其類似於Python包層次結構。這是因爲在模塊中,__name__是Python包命名空間中的模塊名稱。

因此,使用__name__的名稱是推薦,但不是需要。而事實上,你已經明確違反了它:

logger = logging.getLogger('ControllerOne') 

所以,你可以只使用一個單獨的名稱每個線程,通過把一個線程ID或名字進入記錄器名稱。例如:

logger = logging.getLogger('ControllerOne.{}'.format(threading.get_ident()) 

或者,你的情況,因爲你似乎對每個線程的唯一task_id,你可以使用,而不是線程ID。

當然,這意味着你必須真正使用記錄器;你不能只打電話logging.debug。你不能依靠basicConfig;你將需要在每個線程中顯式配置記錄器。因爲每個線程創建自己的獨立ControllerOne例如,明顯的地方這樣做是ControllerOne.__init__;在該功能,你可以調用getLogger用納入線程或任務ID的記錄器名稱,創建並設置FileHandler也包含在名稱中的線程或任務ID,並將其存儲爲self.logger。然後,無論何時你需要記錄一些東西,你只需要做self.logger.debug(…)

如果所有聽起來像官樣文章給你,因爲你不知道一個FileHandler是什麼,你可能需要在HOWTO文檔閱讀至少basic tutorial,但advanced tutorialcookbook也是非常有用的。

相關問題