Sobes.tech
Назад к вопросам
Senior
10

Как реализовать аудит всех HTTP-вызовов в большом монолитном сервисе с множеством контроллеров (время вызова, URL, request/response body, время обработки)?

Компании, где спрашивали
СБК ПАРУС

Ответ от нейросети

sobes.tech AI

Для аудита всех HTTP-вызовов в большом монолитном Java-сервисе с множеством контроллеров оптимально использовать аспектно-ориентированное программирование (AOP) или фильтры/интерсепторы, которые перехватывают запросы и ответы централизованно.

Пример подхода с использованием Spring AOP:

  • Создайте аспект, который будет срабатывать до и после вызова контроллера.
  • В методе "до" сохраните время начала, URL, тело запроса (если нужно).
  • В методе "после" получите тело ответа и время окончания, вычислите длительность.
  • Логируйте или сохраняйте эти данные в хранилище аудита.

Пример кода с использованием Spring AOP:

@Aspect
@Component
public class AuditAspect {

    @Around("@within(org.springframework.web.bind.annotation.RestController) || @annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public Object auditHttpCall(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        // Получение HttpServletRequest через RequestContextHolder
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String url = request.getRequestURI();
        String method = request.getMethod();

        // Чтение тела запроса может потребовать обертки Request

        Object response = joinPoint.proceed();

        long duration = System.currentTimeMillis() - start;

        // Логирование или сохранение в базу
        System.out.printf("[AUDIT] %s %s took %d ms, response: %s\n", method, url, duration, response);

        return response;
    }
}

Также можно использовать фильтры (javax.servlet.Filter) для перехвата запросов и ответов, но AOP удобнее для логики вокруг контроллеров.

Важно учитывать, что чтение тела запроса и ответа может требовать оберток (например, ContentCachingRequestWrapper), чтобы не потерять поток данных.

Такой централизованный подход позволяет масштабировать аудит без изменения каждого контроллера.