diff --git a/src/main/java/in/koreatech/koin/global/exception/GlobalExceptionHandler.java b/src/main/java/in/koreatech/koin/global/exception/GlobalExceptionHandler.java index 55691a218..188476a96 100644 --- a/src/main/java/in/koreatech/koin/global/exception/GlobalExceptionHandler.java +++ b/src/main/java/in/koreatech/koin/global/exception/GlobalExceptionHandler.java @@ -1,9 +1,6 @@ package in.koreatech.koin.global.exception; import java.time.format.DateTimeParseException; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; import java.util.stream.Collectors; import org.springframework.context.support.DefaultMessageSourceResolvable; @@ -17,8 +14,6 @@ import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import org.springframework.web.util.ContentCachingRequestWrapper; -import org.springframework.web.util.WebUtils; import in.koreatech.koin.global.auth.exception.AuthenticationException; import in.koreatech.koin.global.auth.exception.AuthorizationException; @@ -35,7 +30,6 @@ public ResponseEntity handleIllegalArgumentException( IllegalArgumentException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.BAD_REQUEST, e.getMessage()); } @@ -45,7 +39,6 @@ public ResponseEntity handleAuthorizationException( AuthorizationException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.FORBIDDEN, e.getMessage()); } @@ -55,7 +48,6 @@ public ResponseEntity handleAuthenticationException( AuthenticationException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.UNAUTHORIZED, e.getMessage()); } @@ -65,7 +57,6 @@ public ResponseEntity handleDataNotFoundException( DataNotFoundException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.NOT_FOUND, e.getMessage()); } @@ -75,7 +66,6 @@ public ResponseEntity handleDataNotFoundException( DuplicationException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.CONFLICT, e.getMessage()); } @@ -85,7 +75,6 @@ public ResponseEntity handleExternalServiceException( ExternalServiceException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage()); } @@ -95,7 +84,6 @@ public ResponseEntity handleDateTimeParseException( DateTimeParseException e ) { log.warn(e.getMessage()); - requestLogging(request); return buildErrorResponse(HttpStatus.BAD_REQUEST, "잘못된 날짜 형식입니다. " + e.getParsedString()); } @@ -119,7 +107,6 @@ public ResponseEntity handleException( 서버에서 에러가 발생했습니다. uri: {} {} {} """, request.getMethod(), request.getRequestURI(), detail); - requestLogging(request); return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, "서버에서 오류가 발생했습니다."); } @@ -144,7 +131,6 @@ protected ResponseEntity handleMethodArgumentNotValid( ) { HttpServletRequest request = ((ServletWebRequest) webRequest).getRequest(); log.warn("검증과정에서 문제가 발생했습니다. uri: {} {}, ", request.getMethod(), request.getRequestURI(), ex); - requestLogging(request); String errorMessages = ex.getBindingResult().getAllErrors().stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.joining(", ")); @@ -158,47 +144,4 @@ private ResponseEntity buildErrorResponse( var response = new ErrorResponse(httpStatus.value(), message); return ResponseEntity.status(httpStatus).body(response); } - - private void requestLogging(HttpServletRequest request) { - log.info("request header: {}", getHeaders(request)); - log.info("request query string: {}", getQueryString(request)); - log.info("request body: {}", getRequestBody(request)); - } - - private Map getHeaders(HttpServletRequest request) { - Map headerMap = new HashMap<>(); - Enumeration headerArray = request.getHeaderNames(); - while (headerArray.hasMoreElements()) { - String headerName = headerArray.nextElement(); - headerMap.put(headerName, request.getHeader(headerName)); - } - return headerMap; - } - - private String getQueryString(HttpServletRequest httpRequest) { - String queryString = httpRequest.getQueryString(); - if (queryString == null) { - return " - "; - } - return queryString; - } - - private String getRequestBody(HttpServletRequest request) { - var wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class); - if (wrapper == null) { - return " - "; - } - try { - // body 가 읽히지 않고 예외처리 되는 경우에 캐시하기 위함 - wrapper.getInputStream().readAllBytes(); - byte[] buf = wrapper.getContentAsByteArray(); - if (buf.length == 0) { - return " - "; - } - return new String(buf, wrapper.getCharacterEncoding()); - } catch (Exception e - ) { - return " - "; - } - } } diff --git a/src/main/java/in/koreatech/koin/global/log/RequestLoggingFilter.java b/src/main/java/in/koreatech/koin/global/log/RequestLoggingFilter.java index c168d452b..68ea76fe8 100644 --- a/src/main/java/in/koreatech/koin/global/log/RequestLoggingFilter.java +++ b/src/main/java/in/koreatech/koin/global/log/RequestLoggingFilter.java @@ -2,7 +2,10 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -15,6 +18,7 @@ import org.springframework.util.StopWatch; import org.springframework.web.cors.CorsUtils; import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.WebUtils; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; @@ -54,6 +58,9 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha MDC.put(REQUEST_ID, getRequestId(httpRequest)); stopWatch.start(); log.info("request start [uri: {} {}]", httpRequest.getMethod(), httpRequest.getRequestURI()); + log.info("request header: {}", getHeaders(cachedRequest)); + log.info("request query string: {}", getQueryString(cachedRequest)); + log.info("request body: {}", getRequestBody(cachedRequest)); chain.doFilter(cachedRequest, response); } finally { stopWatch.stop(); @@ -76,4 +83,41 @@ private String getRequestId(HttpServletRequest httpRequest) { } return requestId; } + + private Map getHeaders(HttpServletRequest request) { + Map headerMap = new HashMap<>(); + Enumeration headerArray = request.getHeaderNames(); + while (headerArray.hasMoreElements()) { + String headerName = headerArray.nextElement(); + headerMap.put(headerName, request.getHeader(headerName)); + } + return headerMap; + } + + private String getQueryString(HttpServletRequest httpRequest) { + String queryString = httpRequest.getQueryString(); + if (queryString == null) { + return " - "; + } + return queryString; + } + + private String getRequestBody(HttpServletRequest request) { + var wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class); + if (wrapper == null) { + return " - "; + } + try { + // body 가 읽히지 않고 예외처리 되는 경우에 캐시하기 위함 + wrapper.getInputStream().readAllBytes(); + byte[] buf = wrapper.getContentAsByteArray(); + if (buf.length == 0) { + return " - "; + } + return new String(buf, wrapper.getCharacterEncoding()); + } catch (Exception e + ) { + return " - "; + } + } }