2014-03-25 39 views
3

考慮使用python logger模塊的多線程python應用程序。我想爲每個線程進行日誌記錄,所以我在主模塊(創建線程)的記錄器名稱底部追加了一個唯一ID(不是線程ID)。每個線程都使用python登錄

mylogger = logging.getLogger(str(someInt) + __name__) 

現在這個模塊使用多個模塊,這些模塊還支持記錄但記錄器初始化爲

mylogger = logging.getLogger(__name__) 

由於被叫類沒有看到來電者的記錄,來電的日誌線程特定但根據它的路徑,被調用者的文件將進入一個全局文件。

我們可以做些什麼來避免改變每個其他模塊傳遞str(someInt)並且不改變地使用它們,但仍然記錄到線程特定的文件。

請糾正我,如果我錯了任何地方。

回答

0

雖然我並沒有真正體驗過我的建議,但我會嘗試使用Thread-local storage

Thread-local storage

表示線程局部數據的類。線程本地數據是其值爲線程特定的數據 。要管理線程本地數據,只需 創建本地(或子類)的實例並將其存儲在 上。實例的值對於單獨的線程將會有所不同。

然後,您可以保存和訪問下列方式中的變量:

import threading 
mydata = threading.local() 
mydata.x = 1 

我建議保存線程特定記錄器的線程局部變量,當你創建它,然後訪問記錄儀再次需要時通過線程本地存儲。

看一看,它幫助我瞭解線程局部變量:

+0

感謝您的建議。這解決了問題的一部分,即跨模塊傳遞信息。但是,仍然需要更改底層模塊才能訪問線程局部變量,然後將其用作記錄器對象。 –

+0

對不起,我沒有注意到「不變」的部分。你能指定,你可以更改哪部分代碼?或者給我們一些簡單的例子,清楚地說明哪一部分可以修改。 – Marek

0

一個潛在的解決辦法是更換getLogger

import logging 
old_getlogger= logging.getLogger 
def my_getlogger(name): 
    return old_getlogger((str(someInt) if name==__name__ else "") + name) 
logging.getLogger= my_getlogger 

你需要確保someInt雖然具有正確的值,但這可能很難,具體取決於代碼的結構。 @Marek提出的使用線程本地存儲的建議可能對此有用。

+0

@goncaloppp:主要關心的是在不改變下劃線模塊的情況下使其工作。 –

+0

這不會改變底層模塊,它只是在運行時修改'logging'的行爲**。這是一個快速和骯髒的解決方案,但 - 如果你想做的事情正確,鏈接@VinaySajip提供看起來更有希望 – goncalopp

1

我不會推薦一個解決方案,它爲單獨的線程提供單獨的文件:如果將thread/threadName添加到格式字符串中,您總是可以從通用日誌文件中分離出信息。你可以做你要求的,使用Filter子類,如this post中描述的類似(但不完全相同)的用例。

+0

感謝您的建議Vinay。但在我們當前的基礎架構中,由於有100個線程保持產卵和退出,因此幾乎不可能在日誌文件中搜索1個線程ID /名稱。 –