如何在 Spring Boot Actuator 的 Trace 中包含 JSON 响应正文?

问题描述 投票:0回答:4

Spring Boot Actuator 的

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

json spring spring-boot trace spring-boot-actuator
4个回答
8
投票

最近,我写了一篇关于自定义 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;
    }
}

现在,您可以在 JSON

responseBody
端点服务中看到
trace


0
投票

来自一位 Spring 维护者:

从来没有开箱即用地支持跟踪请求和响应正文。对跟踪参数的支持已被删除,因为当请求以 POST 形式发送数据时,需要读取整个请求正文。

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


0
投票

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

httptrace

请参阅完整的相关代码

https://gist.github.com/gberche-orange/06c26477a313df9d19d20a4e115f079f

这需要相当多的重复,希望 springboot 团队能够帮助减少这种重复,请参阅相关

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


0
投票
由于一些最终方法和私有字段,在 2.5.4 中不可能做到这一点。但是,如果您像我一样确实需要它,则可以注销如下响应。

@Component public class RequestTraceFilter extends HttpTraceFilter { public RequestTraceFilter(HttpTraceRepository repository, HttpExchangeTracer tracer) { super(repository, tracer); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { TeeHttpServletResponse teeResponse = new TeeHttpServletResponse(response); filterChain.doFilter(request, teeResponse); teeResponse.finish(); log.info(new String(teeResponse.getOutputBuffer())); super.doFilterInternal(request, teeResponse, filterChain); } }
我还从上面的答案中窃取了TeeHttpServletResponse的使用,将其和TeeServletOutputStream放在与过滤器相同的包中。

© www.soinside.com 2019 - 2024. All rights reserved.