2010-06-04 154 views
2

我們有一個使用線程的系統,以便它可以並行處理不同的功能位。我們希望找到一種將特定「交易」的所有日誌條目捆綁在一起的方法。通常,可以使用'threadName'將它們聚集在一起,但顯然在多線程情況下失敗。跨多線程的Java日誌記錄

通過每個方法調用都沒有傳遞'事務鍵',我看不到一種方法將這些關聯在一起。將密鑰傳遞給每一種方法都很醜陋。

此外,由於我們的系統是基於它的修改版本構建的,因此我們與Java日誌記錄有關。所以,我會對其他平臺感興趣,以尋找我們可能嘗試的例子,但切換平臺極不可能。

有沒有人有任何建議?
謝謝,
彼得

編輯:不幸的是,我沒有在創建線程的控制,則完全由工作流包處理。否則,爲每個線程緩存ID的想法(在ThreadLocal上可能?),然後在創建新線程時將它設置爲一個好主意。無論如何,我可以嘗試。

+0

你可以設置/之前重置線程ID和調用工作的併發位後(嘗試/終於模式),和然後用它來驅動你的日誌? – 2010-06-04 19:06:38

回答

0

如何命名您的線程以包含交易ID?誠然,快速和骯髒,但它應該工作(直到你需要線程名稱的其他東西,或者你開始重用線程池中的線程)。

+0

我不知道你可以做到這一點,所以謝謝,但我使用的是一個工作流程包,所以我不能真正控制線程名稱本身。 – Risser 2010-06-04 18:38:34

1

您可以考慮創建一個全局可訪問的Map,它將Thread的名稱映射到其當前事務ID。在開始一項新任務時,爲該事務生成一個GUID,並在Map中擁有線程註冊本身。對於執行相同任務的任何Thread執行相同操作。然後,當您需要記錄某些內容時,您可以根據當前的Thread的名稱,從全局Map中查找事務ID。 (有點kludgy,但應該工作)

+0

我喜歡這個想法,除了我沒有看到線程的實際生成。由於工作流程包的原因,它不在我的手中。 – Risser 2010-06-04 18:54:45

+0

爲了擴展這個想法,這裏提出的是在逐線程的基礎上排隊記錄的事件。如果在處理期間的*點處*,您知道事務ID,則可以將它與排隊的所有日誌事件相關聯。 如果您正在生成大量日誌事件,則此「隊列」可能仍在文件系統上,並且您使用後處理步驟來轉換threadId - > transactionId。 – 2010-06-04 19:06:57

0

如果你正在登錄,那麼你必須有某種記錄器對象。你應該在每個線程中有一個特定的實例。

  • 向它添加一個名爲setID(String id)的方法。
  • 在線程中初始化它時,使用該方法設置唯一ID。
  • 在每個日誌條目之前預先設置iD。
0

有幾個人建議答案有新產生的線程知道什麼是交易ID。除非我遺漏了一些東西,爲了讓這個ID進入新產生的線程,我必須將它一直傳遞到產生線程的方法中,我寧願不這樣做。

我不認爲你需要將它傳遞下去,而是負責將工作交給這些線程的代碼需要通過transactionID。工作分配者是不是已經擁有了?

1

但是您提到您的交易跨越多個線程,看看log4j如何與綁定的其他信息,以當前線程與MDCNDC類應付。正如以前所建議的,它使用ThreadLocal,但有趣的是log4j如何將數據注入日誌消息。

//In the code:

MDC.put("RemoteAddress", req.getRemoteAddr());

//In the configuration file, add the following:

%X{RemoteAddress}

詳情:

http://onjava.com/pub/a/onjava/2002/08/07/log4j.html?page=3

http://wiki.apache.org/logging-log4j/NDCvsMDC