diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java index 4833cb938317..7faf82f379f4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java @@ -61,6 +61,13 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionHandler { private static final Logger log = LogManager.getLogger(); + /** + * Dedicated logger for 404 NOT_FOUND responses. Configured at OFF level by default + * so that expected 404s don't flood production logs. + * Set to WARN in log4j2.xml to see 404 responses in logs. + */ + private static final Logger notFoundLog = LogManager.getLogger("org.dspace.app.rest.exception.DSpaceApiExceptionControllerAdvice.NotFound"); + /** * Default collection of HTTP error codes to log as ERROR with full stack trace. */ @@ -283,11 +290,9 @@ private void sendErrorResponseFromException(final HttpServletRequest request, if (statusCodesLoggedAsErrors.contains(statusCode)) { log.error("{} (status:{})", message, statusCode, ex); } else { - // Log the error as a single-line WARN StackTraceElement[] trace = ex.getStackTrace(); String location = trace.length <= 0 ? "unknown" : trace[0].toString(); - log.warn("{} (status:{} exception: {} at: {})", - message, statusCode, ex.getClass().getName(), location); + logClientError(statusCode, message, ex.getClass().getName(), location); } response.sendError(statusCode, message); @@ -322,7 +327,6 @@ private void sendErrorResponse(final HttpServletRequest request, // Log the full error and status code log.error("{} (status:{})", message, statusCode, ex); } else if (HttpStatus.valueOf(statusCode).is4xxClientError()) { - // Log the error as a single-line WARN String location; String exceptionMessage; if (null == ex) { @@ -333,14 +337,28 @@ private void sendErrorResponse(final HttpServletRequest request, StackTraceElement[] trace = ex.getStackTrace(); location = trace.length <= 0 ? "unknown" : trace[0].toString(); } - log.warn("{} (status:{} exception: {} at: {})", message, statusCode, - exceptionMessage, location); + logClientError(statusCode, message, exceptionMessage, location); } //Exception properties will be set by org.springframework.boot.web.support.ErrorPageFilter response.sendError(statusCode, message); } + /** + * Log a 4xx client error. 404 NOT_FOUND is sent to a dedicated logger ({@link #notFoundLog}) + * at WARN level, but the logger is set to OFF by default in log4j2.xml (suppressed). + * Set logger to WARN in log4j2.xml to see 404 responses in logs. + */ + private void logClientError(int statusCode, String message, String exceptionMessage, String location) { + if (statusCode == HttpServletResponse.SC_NOT_FOUND) { + notFoundLog.warn("{} (status:{} exception: {} at: {})", message, statusCode, + exceptionMessage, location); + } else { + log.warn("{} (status:{} exception: {} at: {})", message, statusCode, + exceptionMessage, location); + } + } + /** * Get set of status codes that should be treated as errors. * @@ -355,7 +373,6 @@ private Set getStatusCodesLoggedAsErrors() { statusCodesLoggedAsErrors.add(Integer.valueOf(code)); } catch (NumberFormatException e) { log.warn("Non-integer HTTP status code {} in {}", code, P_LOG_AS_ERROR); - // And continue } } return statusCodesLoggedAsErrors; diff --git a/dspace/config/log4j2.xml b/dspace/config/log4j2.xml index 3273551bc0f6..a2ad06ee33a6 100644 --- a/dspace/config/log4j2.xml +++ b/dspace/config/log4j2.xml @@ -89,6 +89,13 @@ + + + + +