Using log4j with Web container (part of the J2EE server)

你离开我真会死。 提交于 2019-12-24 14:42:38

问题


When our application throws errors that we catch, we put the message and stacktrace in a log file created specifically for our application (myapp.log). For example:

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

We do this because since we are in a environment where multiple apps reside on an application server...ours and every other applications logs should be seperate from the server.log.

However, for some cases where we are not catching the error...the stack trace is being written on server.log In these cases also we would like to send stack errors to myapp.log. I know we can define an exception in web.xml and forward to a jsp page but is there a way, in this case, to not send the stack trace to server.log but instead to myapp.log? Other than catching the exception by code change of course.


回答1:


However, for some cases where we are not catching the error...the stack trace is being written on server.log

To me, this is a normal behavior. Some exceptions, for example RuntimeException, are caught by the application server and logged in the app server log file (which is global to a domain with GlassFish). And you don't watch to catch them all, you want the container to do its job in such situation, for example rollbacking a transaction, or you'll get nasty bugs.

In these cases also we would like to send stack errors to myapp.log. I know we can define an exception in web.xml and forward to a jsp page but is there a way, in this case, to not send the stack trace to server.log but instead to myapp.log?

To my knowledge, this is not possible. And even if you add an <error-page>, it's still the app server that will catch the exception so this won't solve your "issue". And even if you use a servlet filter to catch Throwable (I wouldn't do that) and log it at the application level, you'll have to rethrow it to let the container do its job as I mentioned above. So it won't solve your "issue" entirely neither.

Other than catching the exception by code change of course.

Don't do that, you do not want to catch them all!




回答2:


The answer is appserver/webcontainer dependent. This goes beyond the Java EE specification. You need to consult the 'Logging' chapter of its documentation for details. Some may support the construct as you want, but others may not.

Best solution is to have a global exception handler, such as the <error-page> which you mentioned yourself. Let it listen on java.lang.Exception or maybe Throwable. Alternatively you can have (or reuse) a Filter which listens on /* and just put the chain.doFilter(request, response) inside a try-catch block on Exception or maybe Throwable.

Edit: here are some code examples as requested in the comments. First the Filter which listens on /*. The way I explained it before almost writes code itself:

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);
    }
}

Note that I would more recommend to put it in the "front controller" Servlet of your webapplication. I don't know if you're using any (it would have been too obvious to put it there, though) and I also don't know if you're using some existing framework which might already provide out-of-the-box solutions for this.

And the error-page, well, you can't go around an ugly scriptlet to log the exception.

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

Note that this still logs the exception to the server.log. At this point it's already too late to turn.



来源:https://stackoverflow.com/questions/1799406/using-log4j-with-web-container-part-of-the-j2ee-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!