diff --git a/server/src/main/java/com/talkka/server/common/log/HttpLogMessage.java b/server/src/main/java/com/talkka/server/common/log/HttpLogMessage.java new file mode 100644 index 00000000..f62d0204 --- /dev/null +++ b/server/src/main/java/com/talkka/server/common/log/HttpLogMessage.java @@ -0,0 +1,39 @@ +package com.talkka.server.common.log; + +import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.ContentCachingResponseWrapper; + +import lombok.Builder; + +@Builder +public record HttpLogMessage(String httpMethod, String requestUri, Integer httpStatus, String clientIp, + Long elapsedTimeMs, String requestParam, String requestBody, String responseBody) { + public static HttpLogMessage create(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response, + Long elapsedTimeMs) { + return HttpLogMessage.builder() + .httpMethod(request.getMethod()) + .requestUri(request.getRequestURI()) + .httpStatus(response.getStatus()) + .clientIp(request.getRemoteAddr()) + .elapsedTimeMs(elapsedTimeMs) + .requestParam(request.getQueryString()) + .requestBody(new String(request.getContentAsByteArray())) + .responseBody(new String(response.getContentAsByteArray())) + .build(); + } + + public String beatify() { + String format = """ + HTTP REQUEST %s %s %s + | ClientIp: %s + | ElapsedTimeMs: %sms + | RequestParam: %s + | RequestBody: %s + | ResponseBody: %s + """; + + return String.format(format, httpMethod, requestUri, httpStatus, clientIp, elapsedTimeMs, requestParam, + requestBody, responseBody + ); + } +} diff --git a/server/src/main/java/com/talkka/server/common/log/LoggingFilter.java b/server/src/main/java/com/talkka/server/common/log/LoggingFilter.java new file mode 100644 index 00000000..92963bc8 --- /dev/null +++ b/server/src/main/java/com/talkka/server/common/log/LoggingFilter.java @@ -0,0 +1,43 @@ +package com.talkka.server.common.log; + +import java.io.IOException; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.ContentCachingRequestWrapper; +import org.springframework.web.util.ContentCachingResponseWrapper; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +public class LoggingFilter extends OncePerRequestFilter { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + var cachingRequestWrapper = new ContentCachingRequestWrapper(request); + var cachingResponseWrapper = new ContentCachingResponseWrapper(response); + + var startTime = System.currentTimeMillis(); + filterChain.doFilter(cachingRequestWrapper, cachingResponseWrapper); + var endTime = System.currentTimeMillis(); + + try { + var logMessage = HttpLogMessage.create(cachingRequestWrapper, cachingResponseWrapper, + (endTime - startTime)) + .beatify(); + log.info(logMessage); + cachingResponseWrapper.copyBodyToResponse(); + } catch (Exception exception) { + log.error("Logging 실패"); + } + } +}