如何在Spring Boot Actuator的Trace中包括JSON响应主体?

发布于 2021-02-02 11:45:10

Spring Boot Actuator
Trace很好地捕获了输入/输出HTTP参数,标头,用户等。我想扩展它以捕获HTTP响应的主体,这样我就可以全面了解即将发生的事情进入和退出网络层。看一下TraceProperties,似乎没有一种配置响应正文捕获的方法。是否有一种“安全”的方式来捕获响应主体而不会弄乱它发回的任何字符流?

关注者
0
被浏览
111
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    最近,我写了一篇有关自定义Spring Boot Actuator
    trace端点的博客文章,并且在与Actuator一起玩时,我很惊讶这response body不是要跟踪的受支持属性之一。

    我以为我可能需要此功能,并由于Logback的提出了一个快速的解决方案TeeFilter

    为了复制响应的输出流,我无需过多检查就复制并使用了TeeHttpServletResponseTeeServletOutputStream

    然后,就像我在博客文章中解释的那样,扩展WebRequestTraceFilter如下:

    @Component
    public class RequestTraceFilter extends WebRequestTraceFilter {
    
        RequestTraceFilter(TraceRepository repository, TraceProperties properties) {
            super(repository, properties);
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            TeeHttpServletResponse teeResponse = new TeeHttpServletResponse(response);
    
            filterChain.doFilter(request, teeResponse);
    
            teeResponse.finish();
    
            request.setAttribute("responseBody", teeResponse.getOutputBuffer());
    
            super.doFilterInternal(request, teeResponse, filterChain);
        }
    
        @Override
        protected Map<String, Object> getTrace(HttpServletRequest request) {
            Map<String, Object> trace = super.getTrace(request);
    
            byte[] outputBuffer = (byte[]) request.getAttribute("responseBody");
    
            if (outputBuffer != null) {
                trace.put("responseBody", new String(outputBuffer));
            }
    
            return trace;
        }
    }
    

    现在,您可以responseBody在JSON trace端点中看到服务。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看