2009-11-25 43 views
1

當我們的應用程序拋出我們捕獲的錯誤時,我們將消息和堆棧跟蹤放入專門爲我們的應用程序(myapp.log)創建的日誌文件中。例如:在Web容器中使用log4j(J2EE服務器的一部分)

public class SomeClass { 
    OurLogger log = OurLogger.getLogger ("myapp", SomeClass.class); 
    public void someMethod { 
     try { 
     //code 
     } 
     catch (DataAccessException e) 
     { 
      log.error(e.getMessage(), e); 
     } 
    } 
} 

我們這樣做是因爲,因爲我們是在多個應用駐留在應用服務器上的環境......我們和所有其他應用程序日誌,應當從server.log獨立。

但是,對於某些情況下,我們沒有發現錯誤...堆棧跟蹤正在寫入server.log在這些情況下,我們還想將堆棧錯誤發送到myapp.log。我知道我們可以在web.xml中定義一個異常並轉發到一個jsp頁面,但在這種情況下,有沒有辦法將堆棧跟蹤發送到server.log,而不是發送到myapp.log?除了通過代碼更改捕捉異常。

+0

您使用的是什麼應用程序服務器? – 2009-11-25 20:21:16

+0

glassfish v2。但我們有一個處理服務器配置的組。所以對我來說,不容易讓他們做出改變..除非我可以支持:) – Omnipresent 2009-11-25 20:36:22

+0

好的。順便說一句,GlassFish使用Java日誌記錄(而不是log4j)。 – 2009-11-25 21:13:06

回答

1

然而,對於某些情況下,我們沒有捕捉錯誤...堆棧跟蹤正在上的server.log

要我寫的,這是一種正常的行爲。一些例外情況(例如RuntimeException)被應用程序服務器捕獲並登錄到應用程序服務器日誌文件(對於使用GlassFish的域中是全局的)。而且你並沒有注意全部抓住它們,你希望容器在這種情況下完成工作,例如回滾事務,否則你會得到令人討厭的錯誤。

在這些情況下,我們也希望將堆棧錯誤發送到myapp.log。我知道我們可以在網絡中定義一個異常。xml並轉發到jsp頁面,但是在這種情況下,有沒有辦法將堆棧跟蹤發送到server.log,而是發送到myapp.log?

據我所知,這是不可能的。即使你添加了<error-page>,它仍然是應用程序服務器,將捕獲異常,所以這不會解決你的「問題」。即使你使用一個servlet過濾器來捕獲Throwable(我不會這樣做)並將它記錄在應用程序級別,但您必須重新推出它才能讓容器完成其工作,如上所述。所以它不會完全解決你的「問題」。

除了通過代碼更改捕捉異常當然。

不要那樣做,你做不是想抓住他們!

0

答案是appserver/webcontainer相關。這超出了Java EE規範。有關詳細信息,您需要查閱其文檔的「記錄」一章。有些人可能會支持你想要的結構,但有些可能不支持。

最好的解決方案是擁有一個全局異常處理程序,例如您自己提及的<error-page>。讓它聽java.lang.ExceptionThrowable。或者,您可以擁有(或重新使用)Filter,其中收聽/*並將chain.doFilter(request, response)放在try-catch區塊內ExceptionThrowable

編輯:這裏有一些代碼示例,如評論中所要求的。首先在/*上收聽的Filter。我以前解釋它的方式幾乎寫代碼本身:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { 
    try { 
     chain.doFilter(request, response); 
    } catch (Exception e) { 
     logger.error("Caught an uncaught exception.", e); 
     HttpServletRequest req = (HttpServletRequest) request; 
     HttpServletResponse res = (HttpServletResponse) response; 
     req.getRequestDispatcher("error.jsp").forward(req, res); 
    } 
} 

注意,我會更建議把它放在了「前端控制器」你的web應用的Servlet。我不知道你是否在使用任何方法(但是將它放在那裏顯然太明顯了),我也不知道你是否正在使用一些現有的框架,盒子解決方案。

而錯誤頁面,以及你不能繞過一個醜陋的腳本記錄異常。

<% logger.error("Caught an uncaught exception", exception); %> 

注意,這仍然記錄的例外server.log。此時現在已經太晚了。

+0

如果我在web.xml中添加,則會將日誌寫入server.log。順便說一句,我正在使用GlassFish v2。 – Omnipresent 2009-11-25 20:18:38

+0

我應該添加,在特定的錯誤頁面中,您可以自己記錄異常。它在JSP頁面範圍中作爲名爲'exception'的隱式變量提供。 – BalusC 2009-11-25 20:22:16

+0

而且,如果您不**要登錄到'server.log',那麼我會繼續使用過濾器方法並調用catch塊中的錯誤頁面。 – BalusC 2009-11-25 20:23:56