How to include JSON response body in Spring Boot Actuator's Trace?

前端 未结 3 1870
星月不相逢
星月不相逢 2020-12-16 13:41

Spring Boot Actuator\'s Trace does a good job of capturing input/output HTTP params, headers, users, etc. I\'d like to expand it to also capture the body of the

相关标签:
3条回答
  • 2020-12-16 14:05

    With a webflux reactive stack, it is possible to capture http request and response body using spring-cloud-gateway and inject them into actuator httptrace by defining a custom HttpTraceWebFilter.

    See full associated code at https://gist.github.com/gberche-orange/06c26477a313df9d19d20a4e115f079f

    This requires quite a bit of duplication, hopefully springboot team will help reduce this duplication, see related https://github.com/spring-projects/spring-boot/issues/23907

    0 讨论(0)
  • 2020-12-16 14:09

    From one of the spring maintainers:

    Tracing the request and response body has never been supported out of the box. Support for tracing parameters was dropped as, when the request is POSTed form data, it requires reading the entire request body.

    https://github.com/spring-projects/spring-boot/issues/12953

    0 讨论(0)
  • 2020-12-16 14:15

    Recently, I wrote a blog post about customization of Spring Boot Actuator's trace endpoint and while playing with Actuator, I was kinda surprised that response body isn't one of the supported properties to trace.

    I thought I may need this feature and came up with a quick solution thanks to Logback's TeeFilter.

    To duplicate output stream of the response, I copied and used TeeHttpServletResponse and TeeServletOutputStream without too much examination.

    Then, just like I explained in the blog post, extended WebRequestTraceFilter like:

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

    Now, you can see responseBody in the JSON trace endpoint serves.

    0 讨论(0)
提交回复
热议问题