Как включить тело ответа JSON в Spring Trace Boot Actuator?

Spring Boot Actuator Trace выполняет хорошую работу по захвату параметров ввода/вывода HTTP, заголовков, пользователей и т.д. Я хотел бы расширить его, чтобы также захватить тело ответа HTTP, таким образом, я могу иметь полное представление о том, что происходит и выходит из веб-слоя. Глядя на TraceProperties, не похоже, что есть способ настроить захват тела ответа. Есть ли "безопасный" способ захвата тела ответа, не испортив любой поток символов, который он отправляет?

Ответ 1

Недавно я написал блог о настройке конечной точки Spring Boot Actuator trace, и во время игры с Actuator я был несколько удивлен, что response body не является одним из поддерживаемых свойств для отслеживания.

Я подумал, что мне может понадобиться эта функция, и нашел быстрое решение благодаря Logback TeeFilter.

Чтобы продублировать выходной поток ответа, я скопировал и использовал TeeHttpServletResponse и TeeServletOutputStream без особого изучения.

Затем, как я объяснил в сообщении в блоге, расширенный 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.