Improve WebFlux exception logging

This commit updates HttpWebHandlerAdapter and
ResponseStatusExceptionHandler in order to specify the method/uri in the
logged message.

It also logs a WARN message for bad request (400) HTTP responses in
order to get some logs when an exception is thrown due to client error
(unable to deserialize request body for example).

Issue: SPR-16447
This commit is contained in:
sdeleuze 2018-02-02 12:53:43 +01:00
parent fdde9de005
commit 196f3f8cc1
2 changed files with 21 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -182,7 +182,7 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
ServerWebExchange exchange = createExchange(request, response);
return getDelegate().handle(exchange)
.onErrorResume(ex -> handleFailure(response, ex))
.onErrorResume(ex -> handleFailure(request, response, ex))
.then(Mono.defer(response::setComplete));
}
@ -191,7 +191,7 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
getCodecConfigurer(), getLocaleContextResolver(), this.applicationContext);
}
private Mono<Void> handleFailure(ServerHttpResponse response, Throwable ex) {
private Mono<Void> handleFailure(ServerHttpRequest request, ServerHttpResponse response, Throwable ex) {
if (isDisconnectedClientError(ex)) {
if (disconnectedClientLogger.isTraceEnabled()) {
disconnectedClientLogger.trace("Looks like the client has gone away", ex);
@ -204,7 +204,8 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
return Mono.empty();
}
if (response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR)) {
logger.error("Failed to handle request", ex);
logger.error("Failed to handle request [" + request.getMethod() + " "
+ request.getURI() + "]", ex);
return Mono.empty();
}
// After the response is committed, propagate errors to the server..

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
@ -42,11 +43,24 @@ public class ResponseStatusExceptionHandler implements WebExceptionHandler {
if (ex instanceof ResponseStatusException) {
HttpStatus status = ((ResponseStatusException) ex).getStatus();
if (exchange.getResponse().setStatusCode(status)) {
logger.trace(ex.getMessage());
if (status.is5xxServerError()) {
logger.error(buildMessage(exchange.getRequest(), ex));
}
else if (status == HttpStatus.BAD_REQUEST) {
logger.warn(buildMessage(exchange.getRequest(), ex));
}
else {
logger.trace(buildMessage(exchange.getRequest(), ex));
}
return exchange.getResponse().setComplete();
}
}
return Mono.error(ex);
}
private String buildMessage(ServerHttpRequest request, Throwable ex) {
return "Failed to handle request [" + request.getMethod() + " "
+ request.getURI() + "]: " + ex.getMessage();
}
}