Filter级别统一异常处理(异常记录日志)

1.介绍

项目中要做一个转发系统(gateway),转发到的第三方系统可能是web service或者http。采取在filter级别做流向控制,web service的请求由系统内部自己处理,用的apache cxf框架,http的请求由zuul做转发处理。为了记录每一次请求的详情并记录入库,如入参、出参、头信息、请求用户和异常等,在刚进入最外层的filter时创建log对象,并放到ThreadLocal中,在doFilter之后将日志记录入库。

2.遇到的问题

在使用中,发现一旦遇到不可预知的异常,线程终止,程序无法走到记录日志入库那一步,导致记录缺失。

3.解决方案

参考Spring框架中日志记录的案例,在org.springframework.web.filter.AbstractRequestLoggingFilter中有体现。

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    boolean isFirstRequest = !isAsyncDispatch(request);
    HttpServletRequest requestToUse = request;

    if (isIncludePayload() && isFirstRequest && !(request instanceof ContentCachingRequestWrapper)) {
        requestToUse = new ContentCachingRequestWrapper(request, getMaxPayloadLength());
    }

    boolean shouldLog = shouldLog(requestToUse);
    if (shouldLog && isFirstRequest) {
        beforeRequest(requestToUse, getBeforeMessage(requestToUse));
    }
    try {
        filterChain.doFilter(requestToUse, response);
    }
    finally {
        if (shouldLog && !isAsyncStarted(requestToUse)) {
            afterRequest(requestToUse, getAfterMessage(requestToUse));
        }
    }
}

可以看到,此处用try finally进行了巧妙的处理,不管doFilter里面发生了什么,都进行日志处理。
最终我们仿照这段代码,解决了问题。代码如下:

Throwable myThrowable = null;
try {
    filterChain.doFilter(servletRequest, servletResponse);
} catch (Throwable throwable) {
    // 记录外抛异常
    myThrowable = throwable;
    throw throwable;
} finally {
    // 记录在doFilter里被程序处理过后的异常,可参考 http://www.runoob.com/servlet/servlet-exception-handling.html
    Throwable throwable = (Throwable) httpRequest.getAttribute("javax.servlet.error.exception");
    if (throwable != null) {
        myThrowable = throwable;
    }
    //日志记录
    LogUtils.postLog(myThrowable);
    //处理ThreadLocal
    ThreadLocals.removeAll();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容