2009-08-26 46 views
2

,所以我們在使用的Log4j我們的J2EE應用程序是這樣的Log4j到configureAndWatch()產卵數千個線程

public class CustomerController 
{ 
    private static Logger logger = Logger.getLogger(CustomerController.class); 

    public CustomerService customerservice = null; 

    public CustomerController() throws Exception 
    { 
      PropertyConfigurator.configureAndWatch("c:\log4j.property", 50000); 

      customerservice = ServiceManagerSingleton.getCustomerServiceInstance(); 
    } 
} 

這樣我們就可以更改日誌級別的實時。非常便利。我們大多數課程都是像這個控制器一樣設置的。我們使用單例模式,這樣我們只有一個eash類的實例;一次調用PropertyConfigurator.configureAndWatch()爲每個類調用一次。

問題:每週大約兩次我們的應用程序服務器死亡並創建一個堆轉儲。從IBM使用堆分析我們可以看出,似乎有很多相關的Log4j的線程:

808 (0%) [200] 9 org/apache/log4j/PropertyWatchdog 0x14282ad8 

的約3萬總。所以這可能是突然崩潰的原因。

  1. 我們是否正確設置它?
  2. 當EAR重新部署時,所有這些線程會發生什麼?
+0

您是否在使用Spring? – serg 2009-08-26 22:20:48

回答

4

真的是你需要做的是使用你的應用程序服務器的啓動程序(它們都是不同的)來初始化log4j的系統。由於Log4j依賴於靜態變量,因此它本身並不能獨立工作(它可以,但實際上取決於應用程序服務器)。在大多數情況下,整個應用服務器的配置真的是全局的。

您需要確保PropertyConfigurator.configureAndWatch方法只被調用一次。一種方法是在JNDI中添加一些東西。

很多這將取決於應用程序服務器給你什麼。例如,我們使用JBoss,並將Log4J配置爲它的一部分,您只需更改log4j.xml文件以包含您的類需要的內容。 JBoss確保它是動態完成的。

編輯:Here是Websphere創建自定義服務的指示信息,並且您將在其中創建log4J配置,並對文件進行監視。一些警告。您將不得不將log4j.jar添加到應用程序服務器本身的類路徑中,以便它可用於戰爭或耳朵(我敢肯定,無論如何這都可以工作),並且定製服務可能不會在耳朵裏工作。

Here是一種替代方案,它可以將所有內容都保存在戰爭或耳朵中,但代價是動態加載日誌更改。

+0

你有代碼示例嗎? – Tommy 2009-08-26 22:34:12

+1

你在使用什麼應用程序服務器? – Yishai 2009-08-26 22:46:51

+0

WebSphere Application Server – Tommy 2009-08-26 23:23:28

7

CustomerController實例多久創建一次?每次請求一次?因爲我相信configureAndWatch()會在每次調用時產生一個新的線程。

另外,如果你不知道,the log4j docs caution against using this feature在J2EE環境:

因爲到configureAndWatch啓動獨立wathdog線程,因爲沒有辦法在log4j的1.2,則到configureAndWatch方法停止該線程在應用程序被回收的J2EE環境中使用是不安全的。

我知道你不使用Spring,但在我看來Spring類Log4jWebConfigurer has a better explanation爲什麼這個功能在J2EE危險:

警告: Log4j的看門狗線程不會終止,直到VM關機;特別是,它不會在LogManager關閉時終止。因此,建議不要在生產J2EE環境中使用配置文件刷新;看門狗線程在應用程序關閉時不會停止。

更新:在log4j的源來看,每次調用configureAndWatch()確確實create a new thread

+0

沒有它的唯一創建一次。我猜有一個原因,線程在J2EE中通常是不行的... – Tommy 2009-08-27 10:39:40

0

你看過logback,log4j後繼嗎?它處理重新加載其配置in thread或通過JMX。這兩種方法避免了通過調用PropertyConfigurator.configureandWatch()或DOMConfigurator.configurator導致的頭痛。同樣有趣的是,通過配置文件(不需要自定義代碼)啓用了線程內部方法。

0

所有記錄器共享相同的配置文件,因此如果每個使用記錄器的類都包含此初始化代碼,則每個configureAndWatch()調用都可能會產生一個新的觀察器線程。 (恕我直言,Log4j應該知道更好,並允許每個配置文件最多一個觀察者線程,但顯然它不)

+0

這是不正確的。查看log4j源代碼,每次調用configureAndWatch()時都會創建一個線程。 – 2009-08-27 11:23:20