2013-01-09 166 views
14

我構建了一個部署到在Linux上運行的WebSphere Portal Server的Portlet應用程序。每個portlet WAR使用log4j對於這樣的配置記錄,讓每WAR兩個日誌文件:Log4j突然停止登錄

log4j.logger.im.the.package=DEBUG, InfoAppender, DebugAppender 

log4j.appender.InfoAppender=org.apache.log4j.RollingFileAppender 
log4j.appender.InfoAppender.Threshold=INFO 
log4j.appender.InfoAppender.File=/tmp/infoWARName.log 
log4j.appender.InfoAppender.layout=org.apache.log4j.PatternLayout 
log4j.appender.InfoAppender.layout.ConversionPattern=%d %p [%c] - %m%n 

log4j.appender.DebugAppender=org.apache.log4j.RollingFileAppender 
log4j.appender.DebugAppender.Threshold=DEBUG 
log4j.appender.DebugAppender.File=/tmp/debugWARName.log 
log4j.appender.DebugAppender.layout=org.apache.log4j.PatternLayout 
log4j.appender.DebugAppender.layout.ConversionPattern=%d %p [%c] - %m%n 

部署後,一切正常般的魅力和日誌文件開始填寫。幾個小時後,同時,記錄停止,並且info.logdebug.log根本沒有更新。我們需要在服務器中重新部署Portlet WAR以重新開始日誌記錄。

任何想法?

更新:

我開始懷疑它與我的日誌罐子做的。目前,這是JAR的我WEB-INF/lib文件夾中:

com.springsource.org.apache.commons.logging-1.1.1.jar 
com.springsource.org.apache.log4j-1.2.15.jar 
com.springsource.slf4j.api-1.5.6.jar 
slf4j-log4j12-1.5.6.jar 

第二次更新:

在從賞金到幾個小時,這是Log4j的是如何在每一個Portlet應用程序配置。下面是web.xml

<context-param> 
    <param-name>log4jConfigLocation</param-name> 
    <param-value>classpath:miAppLog4j.properties</param-value> 
</context-param> 
<listener> 
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
</listener> 

而且miAppLog4j.properties文件所在文件夾外部的戰爭和門戶。我們通過Shared Library in WebSphere Portal在Portlet Classpath中使其成爲可用。

+2

你有沒有檢查'/ tmp'中是否有足夠的空間存放日誌? – tcb

+0

我檢查過了,硬盤上有足夠的空間:只有4%被使用 –

+0

你檢查了SystemOut.log嗎? – keuleJ

回答

0

我想嘗試移動除臨時文件系統以外的其他位置的日誌文件位置。

+0

我會嘗試。有什麼理由要這樣做?或者任何已知的問題? –

+2

我猜測操作系統可能試圖刪除該文件,因爲該文件位於/ tmp中,所以應該可以自由執行。如果日誌文件在幾秒鐘內變得不可寫入,我已經看到Log4j完全停止寫入 - 當它變爲可寫時,它不會再次開始寫入。 – GreyBeardedGeek

+0

將日誌文件移至/ home,問題仍然存在。儘管log4j config文件仍然位於/ tmp –

3

我認爲問題在於你有多個WAR寫入同一個日誌文件。根據我們的經驗,log4j無法可靠地執行此操作,特別是對於滾動的appender。當人們推出時,其他人就會感到困惑,無法進一步登錄。或者繼續登錄到舊文件。

我懷疑你將不得不讓每個WAR日誌到不同的文件。

+1

每個WAR都有自己的Log4j配置及其專有的日誌文件。我對原始問題做了一些編輯,使其更清楚。 –

22

你提供一些基本信息,所以我只能畫出一些候選人的原因和可能性:

1.問題的文件鎖/手柄/ IO流

  • 通過日誌Triggerred滾動?

    對您的情況有負面影響。對於任何給定的WAR,您的兩個單獨的日誌文件(信息和調試)將同時停止。 每個文件都以默認最大大小(10MB)滾動。兩個日誌總是在同一時間滾動是不太可能的。錯誤不能由日誌滾動觸發。通過配置進行額外確認log4j.appender.InfoAppender.MaxFileSize=200MB

  • 由用戶操縱Linux文件觸發?

    對您的情況有負面影響。用戶/系統管理員操作文件可能會創建鎖定或陳舊的文件句柄。 Linux應該永遠不會對用戶產生問題尾部 -ing一個文件(但窗口確實)。 Linux可能會在用戶壓縮或編輯文件時遇到問題。但是你的問題似乎是非常可重複的,除非你有自動化的腳本處理日誌文件,否則這種情況不太可能發生。

  • 通過Websphere或Spring中的「競爭」配置設置觸發,通過服務器/框架重複使用相同的日誌文件?

    似乎不太可能在你的情況。似乎你還沒有設置Websphere公共日誌記錄配置。通用日誌被自動包括在WebSphere服務器父ClassLoader和可以通過配置被配置成「包裝」到Log4J的:

    文件commons-logging.properties

    # Set application classloader mode as PARENT_LAST when deploying in WAS as .ear 
    priority=1 
    org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl 
    
  • 由硬件問題/磁盤觸發失敗?

    ???似乎很奇怪,這樣的問題會非常重複。

2. java線程問題?

  • 線程死亡或死鎖在「其他」代碼
  • 海量線程處理/爭用,所以用日誌記錄代碼不運行

    從你的描述,我假定應用程序仍在運行並與正常的性能和功能正常工作,但日誌不寫。你可否確認?如果是這樣,那麼它不是webapp線程的線程問題。

    而且我可以證實,它不是Log4J的邏輯中的一個線程問題,因爲只有一次創建/使用它自己的線程是當使用AsynchAppender/ExternallyRolledFileAppender/SocketAppender/TelnetAppender的一個或當PropertyConfigurator.configureAndWatch或調用DOMConfigurator.configureAndWatch方法。

    Negative

3.更改類加載器中的類Log4J的,與使用不同的配置呢?

  • 父類加載器上有衝突的webapp的ClassLoader

    例如你的web應用程序最初是從WEBINF目錄自己配置的類開始的,並且一切都很好,但是稍後一段時間不同的應用程序導致(或者其中一個門戶網站服務器管理工​​具)導致碰撞類被加載到父類ClassLoader中,並且你的應用程序「拾起」這個新的非法版本的類並失敗。

    很可能是一個問題 - Google上成千上萬的用戶都在使用Websphere類加載器。

建議操作:

  • 確保您所有的web應用程序使用PARENT_LAST類加載 -

  • 去管理控制檯,並確保他們PARENT_LAST集中的所有Web應用程序的配置中確保您將Log4J內部錯誤消息寫入控制檯 例如通過在應用程序運行時強制刪除錯誤日誌作爲管理員進行故意測試,創建一個陳舊的句柄。如果「Log4J:」錯誤消息沒有出現在控制檯中,那麼這是一個嚴重的問題。
    下次發生問題時,請收集任何此類控制檯消息並報告它們。另外,您可以在JVM/websphere啓動時設置「-D log4j.debug」,以便精確地找出Log4J在問題出現之前/期間所做的事情 - 消息將發送到控制檯。

  • 您是否確實需要將日誌級別設置爲DEBUG才能爲您的所有軟件包&類?最好設置爲INFO或WARN,並且只有在調試特定問題時纔有選擇地設置。

這是很多文字..........乙^)

+0

我增加了一些額外的細節,也許他們可以提供幫助 –

5

在過去的5年中,Log4j的幾乎沒有固定的任何錯誤:它實際上是一個死的項目。 如果可以的話,考慮用Logback替換它,它直接實現SLF4j。

Logback和SLF4J是由編寫Log4J(Ceki)的同一個人編寫的,擁有更自由的許可證並且擁有良好的社區。它是Log4J 1的繼任者,除了它的名字外。

-3

我不知道爲什麼log4j在您的應用程序停止。但是你可以(應該)升級到log4j 2.0。切換不應該很費力。您需要將log4j.properties文件重寫爲XML文件,因爲新版本不再支持屬性文件。

在Java雜誌中,一篇文章指出log4j 2.0在多線程環境中表現得更加健壯,因此它有可能解決您的問題。如果不是,你仍然有新版本的好處。

它帶來了一些不錯的功能和增強功能(從log4j網站複製):

API分離

的Log4j提供的API是從實現分離並明確應用程序開發人員哪些類和方法他們可以使用,同時確保向前兼容這使得Log4j團隊能夠以兼容的方式安全地完成實施。

改進的性能比Log4j的1.x的速度在關鍵領域

的Log4j 2執行和同樣在大多數情況下的logback。請參閱性能瞭解更多信息。 支持多種API 雖然Log4j 2 API將提供最佳性能,但Log4j 2提供對SLF4J和Commons Logging API的支持。配置的

自動重新加載

喜歡的logback,Log4j的2可自動修改後重新加載其配置。與Logback不同,它將這樣做,而不會在重新配置發生時丟失日誌事件。

高級濾波

喜歡的logback,Log4j的2個支持篩選基於上下文數據,標記,正則表達式,以及其他部件在日誌事件。篩選可以指定爲在傳遞給記錄器或通過Appender時應用於所有事件。另外,過濾器也可以與記錄器相關聯。與Logback不同,您可以在任何這些情況下使用通用的Filter類。

插件架構

Log4j的用於配置部件插件圖案。因此,您不需要編寫代碼來創建和配置Appender,佈局,模式轉換器等等。 Log4j會自動識別插件並在配置引用它們時使用它們。

屬性支持

可以在配置引用屬性是,log4j將直接替換它們,或將Log4j中它們傳遞到,將動態解決這些問題的基礎組件。屬性來自配置文件中定義的值,系統屬性,環境變量,ThreadContext映射和事件中存在的數據。用戶可以通過添加自己的Lookup Plugin來進一步定製屬性提供程序。