在Tomcat上的HTTP状态代码500在ClientAbortException / BrokenPipe上的AccesLog

时间:2017-08-21 13:45:25

标签: tomcat spring-boot access-log

我们使用Kibana设置了一些仪表板和可视化,以监控tomcat为我们的Spring启动Web应用程序生成的accessLog。

我们特别注意已使用状态码5xx回答的请求。

事实证明,如果客户端请求资源并且请求正在进行时取消请求(ClientAbortException/BrokenPipe错误),则ResponseCode设置为500并且应用程序日志中不会记录任何错误(这有点好。)

我们现在想要将ResponseCode更改为不同于500的内容,以便更好地区分" real"内部服务器错误,以及"预期的连接中止,由客户端启动"。

因此我按如下方式实现了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);
  }
}

事实证明,statusCode 500由tomcat / catalina / coyote内部设置,不能从外部更改(因为响应设置为提交)。

是否有可能以某种方式区分&#34;真实&#34;内部服务器错误和&#34;只是&#34;连接中止?

1 个答案:

答案 0 :(得分:0)

事实证明,这似乎是不久前用Tomcat引入的

  

8.5.12起   
8.0.42起   
7.0.76起

并且计划是将其还原为记录应用程序设置的状态代码,而不是500:see discussion here

另一种解决方法可能是将%{javax.servlet.error.exception}r添加到访问日志模式server.tomcat.accesslog.pattern=,这将注销类似的内容。

  

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

并通过ELK过滤掉这些条目。