Код состояния HTTP 500 в Tomcat AccesLog на ClientAbortException/BrokenPipe

Мы настроили несколько информационных панелей и визуализаций с помощью Kibana для мониторинга наших журналов доступа, созданных tomcat для нашего веб-приложения с весенней загрузкой.

Мы уделяем особое внимание запросам, на которые был получен ответ с кодом состояния 5xx.

Как оказалось, если клиент запрашивает ресурс и во время выполнения запроса отменяет запрос (с ошибкой ClientAbortException/BrokenPipe), для ResponseCode устанавливается значение 500, и в журналах приложения не регистрируется никаких ошибок (что вроде нормально).

Теперь мы хотели изменить ResponseCode на значение, отличное от 500, чтобы лучше отличать «настоящие» внутренние ошибки сервера от «ожидаемых прерываний соединения, инициированных клиентом».

Поэтому я реализовал ExceptionHandler следующим образом:

@RestControllerAdvice
public class HttpRequestExceptionHandler {

  private final static Logger LOGGER = LoggerFactory.getLogger(HttpRequestExceptionHandler.class);

  @ExceptionHandler(value = { ClientAbortException.class })
  @ResponseBody
  public ResponseEntity<String> exceptionHandler(Exception e, HttpServletResponse res) {
    res.setStatus(299);
    //res.sendError(299);
    LOGGER.error(""+res.getStatus());
    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
  }
}

Однако, как выясняется, статусCode 500 устанавливается внутренними органами tomcat/catalina/coyote и не может быть изменен извне (поскольку ответ установлен как зафиксированный).

Можно ли как-то отличить «настоящие» внутренние ошибки сервера от «просто» разрывов соединения?


person icyerasor    schedule 21.08.2017    source источник


Ответы (1)


Как оказалось, это, кажется, было введено не так давно, с Tomcat

8.5.12 и новее
8.0.42 и новее
7.0.76 и новее

и планируется вернуться к регистрации кода состояния, установленного приложением, вместо 500: см. обсуждение здесь.

Другим обходным путем может быть добавление %{javax.servlet.error.exception}r к шаблону журнала доступа server.tomcat.accesslog.pattern=, что приведет к выходу из системы, например...

... org.apache.catalina.connector.ClientAbortException: java.io.IOException: Eine bestehende Verbindung wurde ...

и отфильтровать эти записи через ELK.

person icyerasor    schedule 21.08.2017