【问题标题】:How to include JSON response body in Spring Boot Actuator's Trace?如何在 Spring Boot Actuator Trace 中包含 JSON 响应正文?
【发布时间】:2016-03-07 16:23:58
【问题描述】:

Spring Boot Actuator 的 Trace 在捕获输入/输出 HTTP 参数、标头、用户等方面做得很好。我想扩展它以捕获 HTTP 响应的主体,这样我就可以拥有一个进出 Web 层的内容的完整视图。查看TraceProperties,似乎没有配置响应正文捕获的方法。是否有一种“安全”的方式来捕获响应正文,而不会弄乱它发回的任何字符流?

【问题讨论】:

    标签: json spring spring-boot trace spring-boot-actuator


    【解决方案1】:

    最近,我写了一篇关于 Spring Boot Actuator 的 trace 端点自定义的 blog post,在使用 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;
        }
    }
    

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

    【讨论】:

    • 我尝试使用这个答案。从上面复制了确切的代码以及两个类 TeeHttpServletResponse 和 TeeServletOutputStream。现在 / trace 给我 500 和“在响应提交后不能调用 sendError() ”,任何其他资源给我 200 和正文“语法错误”。在 spring 日志中我看不到任何错误
    • RequestTraceFilter.java的包应该和TeeHttpServletResponse 一样,因为teeResponse.finish()teeResponse.getOutputBuffer()是私有方法。
    • 在 Spring Boot 2 中,该类已移至 HttpTraceFilter
    • 我们能否获得有关如何在 Spring Boot 2.3.x 中执行此操作的更新
    【解决方案2】:

    来自 Spring 维护者之一:

    开箱即用从未支持跟踪请求和响应正文。取消了对跟踪参数的支持,因为当请求是 POST 表单数据时,它需要读取整个请求正文。

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

    【讨论】:

      【解决方案3】:

      使用 webflux 响应式堆栈,可以使用 spring-cloud-gateway 捕获 http 请求和响应体,并通过定义自定义 HttpTraceWebFilter 将它们注入到执行器httptrace

      https://gist.github.com/gberche-orange/06c26477a313df9d19d20a4e115f079f查看完整的相关代码

      这需要相当多的重复,希望springboot团队能帮助减少这种重复,见相关https://github.com/spring-projects/spring-boot/issues/23907

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-26
        • 1970-01-01
        • 2023-02-02
        相关资源
        最近更新 更多