2010-10-05 24 views
9

還有巨大並行運行的線程數連續(讓我們假設這個連續部分))。所有線程都想記錄一些應用程序數據,基本上是一組值。如何從多個線程記錄數據?

  1. 什麼是最好的方法來記錄這些數據?單個/多個文件?
  2. 什麼是最好的方法來備份這個日誌?
  3. 從備份文件讀取數據並將其轉換爲有用的東西的方法是什麼?

thisthis等幾個線程建議log4net和log4j,但我想知道實際的過程?另外多個線程如何寫入相同的日誌文件?每個線程都需要文件級鎖嗎?這一切如何工作?

任何指向瞭解所有細節的指針,將不勝感激。

謝謝。

+0

通常情況下,日誌記錄方法將被同步,以便您不必擔心從多個線程訪問它。至於備份,大多數文件系統在文件系統級別都有影子副本 - 我懷疑你應該在應用程序中擔心這一點。 – Joey 2010-10-05 12:21:49

+1

使用日誌記錄框架的意義恰恰在於,它可以讓您免於擔心所有這些細節。 – 2010-10-05 12:24:23

+0

@Michael Borgwardt:我明白你的觀點,但我想知道細節。 – understack 2010-10-05 12:29:14

回答

6

像log4j這樣的庫將能夠配置您的需求。

  1. 拆分成太多的文件會使調試某些問題變得困難,但是讓一個單片文件留下一堆混合進程。我會爲每個原子進程提供一個文件,也就是說,郵件管理器可能會使用自己的日誌文件。 jdbc的額外調試信息可能有其自己的日誌文件,但錯誤和主要事件仍會在主應用程序日誌中報告。

  2. 主要日誌記錄庫支持日誌拆分和旋轉。對於一個使用良好的Web應用程序,我更喜歡爲每一天製作一個日誌文件,並且還可以分割一定的大小。您可以構建一個cron來壓縮較早的日誌,並根據應用程序,您可能需要將它們備份幾個月或無限期。

  3. 就調試的有用性而言,您可以grep某些字符串,例如「Exception」來報告。如果您正在查找統計數據,除了流程日誌之外,您還應該爲該特定目的製作日誌。

日誌可以是同步或異步的,而後者通常對性能最好。通常,消息隊列被建立,然後由單獨的線程寫入。所以多線程可以寫入內存中的一個隊列或緩衝區,一個線程將鎖定和寫入文件。它幾乎在後臺,除非你正在編寫大量的數據,否則你不必考慮它。

+0

用於提及異步日誌 – 2010-10-05 13:09:11

1

關於第1點,我通常將所有內容(與功能相關的)記錄到同一個文件中,但日誌行總是包含一些上下文信息,允許我跟蹤上下文/請求的流程(通過grep或其他)。

例(看漲期權的情況下):

DEBUG|CallID#12: Establishing new AUDIO call from AA to BB 
DEBUG|CallID#34: Call accepted by ZZ at ... 
DEBUG|CallID#99: Call terminated by callee (SS) 

這樣,如果有人問這是「發生了什麼事,在今天12:34從AA到BB打電話?」我只是想要AA或BB(或者它發生的時間),然後,一旦我獲得了呼叫ID,獲取呼叫的全部細節就只需要再次使用該ID進行查詢。

其他的東西,如聊天,存在等將在其自己的文件(將這些信息混合在一個單一的文件中沒有多大意義)。

如果您希望每個線程(而不是每個操作/請求)只記錄正在執行操作的線程的名稱。

關於第2點,每日輪換log4j。

不知道我明白了點3 ...也許你的意思是解析日誌文件來檢索一些模式?任何支持正則表達式的工具都可以做到這一點(grep是最方便的)。

+0

http://logging.apache.org/log4j/1.2/manual.html向下滾動到「性能」。應該給你一些提示。 – biasedbit 2010-10-05 12:34:18

1

正如上面的評論已經說明的那樣,日誌框架的存在正是爲了讓您免於擔心這樣的低級細節。 Log4J或其後繼例如LogBack可以安全有效地處理由多個線程進行的日誌記錄。您只需告訴日誌框架要記錄什麼以及在哪裏,並且它一切正常(通常:-)

對於記錄線程特定的數據,您可以考慮使用診斷上下文。這個earlier answer of mine用一個Log4J的例子解釋了這個。在Logback中,它已被重命名爲Mapped Diagnostic Context

至於備份和後期處理,全部取決於您的實際目標。通常簡單的腳本或像gzipgrep這樣的單個命令就是您所需要的。沒有具體的信息很難說更多。