2011-09-21 68 views
5

我們遇到了一個奇怪的問題。 場景:我們有3個服務器,其中有多個組件實例,都將事務日誌寫入單個日誌文件。我們使用log4j和服務器運行在Java 1.3中。 setAppend()傳遞true並且實現是DailyRollingFileAppenderLog4j dailyrollingfileappender文件問題

問題:在午夜,我們期待當前日誌文件翻轉一個新文件名並開始寫入新文件。這在我們的測試設置(單服務器寫日誌)中運行良好。在生產中,在午夜,新文件正在創建新的日誌正在寫入,但滾動文件正在刪除

任何幫助將高度讚賞,因爲它的幾天,我們無法獲得任何線索問題。

+0

你可以發佈你的配置文件嗎? –

+0

感謝您的回覆。我在這裏找到了一個鏈接[http://vivekagarwal.wordpress.com/2008/02/09/missing-log4j-log-files-with-dailyrollingfileappender-when-they-should-roll-over/]。將嘗試這個,並給予更新 – rajesh

+0

我們繼續在上面的鏈接提供的解決方案,它的工作。 – rajesh

回答

4

不應日誌由許多方法相同的文件。 Log4j是線程安全的,但如果我可以這樣說的話,它不是過程安全的;它不能用作不同java進程之間的共享庫。嵌入到一個Java應用程序中的Log4j不具有其他任何知識。

側翻它會導致你剛剛發現了這個問題:所有的進程中運行自己的代碼側翻,盲目地覆蓋以前的內容(因爲他們沒有任何希望)。

一個可能的解決方案在這裏:Log4j Logging to a Shared Log File

+1

**基於FileAppender的類中的基礎文件打開,追加並關閉,並保存每個日誌部分** 這是真的嗎?我不確定。至少在UNIX上,如果您登錄到文件,然後從命令行中截斷它,則在下一次寫入時會看到在寫入消息之前文件被填充了二進制零。這將表明文件沒有關閉並在每個日誌事件中打開(這會很昂貴),但事實上文件指針在寫入之間保持不變。消息不會混合在一起,因爲對文件系統的底層寫入是原子性的。 – Tim

+0

你說得對。大約兩年前,我不記得自己在想什麼,但沒有證據支持我的理論。我現在只能道歉。 – MaDa

2

我們遇到了同樣的問題。根本的問題是,有沒有辦法協調訪問記錄在多個流程文件(在這種情況下,在多臺服務器上運行)。這意味着各種各樣的不好的事情發生了:記錄被覆蓋,文件無法滾動等...

我給你的建議是讓每個服務器寫入到一個單獨的文件,然後在後處理作業合併。

1

說你已經配置DailyRollingFileAppender每日旋轉(它可以被配置爲旋轉每隔一小時,分鐘等)。說,現在是2014年12月31日,日誌文件名是sample.log。日誌輪換將以下列方式發生:

  • 午夜後收到的第一條日誌消息(例如2015年1月1日凌晨1點)將觸發日誌文件輪換。
  • 日誌文件輪換將首先刪除具有前一天後綴的任何現有文件。 (即它將刪除名稱爲sample-2014-12-31.log的任何文件。理想情況下,不應該存在這樣的文件。)。
  • 然後它會重命名當前文件與前一天的後綴。即,它重新命名sample.log採樣2014-12-31.log
  • 它會創建沒有後綴的新日誌文件。即新的sample.log
  • 它將開始寫入新文件sample.log

如果兩個日誌管理器實例指向相同的日誌文件,那麼每個實例將獨立地在同一文件上重複上述步驟。這可能發生在以下任何情況下:

  • 如果在同一個容器中部署的兩個或多個WAR文件指向同一個日誌文件。
  • 如果兩個或更多進程指向相同的日誌文件。

這種情況會導致在問題中提到的問題。

  • 在Windows機器上,一旦第一個進程已經輪轉日誌文件並獲得新文件的句柄,第二個日誌appender將無法寫入日誌。
  • 在Linux機器上,第二個進程將刪除第一個進程創建的歸檔文件,並將新文件(當前正在被第一個進程使用)重命名爲前一天的文件。因此,第一個進程將開始在前一天的文件中寫入日誌,第二個進程將把日誌寫入新文件。午夜後,第一個進程使用的日誌文件將被刪除。所以,來自第一個進程的日誌將不斷丟失。
+0

我們在我們的Web應用程序中看到非常類似的行爲 - 尚未確定爲什麼我們可能有多個LogManager。 – sbarlster

+1

@sbarlster - 當機器上運行的兩個war文件(或兩個獨立進程)具有相同的日誌文件名時,通常會發生這種情況。 – Bipul

相關問題