From 9d1e896edc24c031bb035eee147bb2c0fe0ab5bd Mon Sep 17 00:00:00 2001 From: catomat0 Date: Wed, 8 Apr 2026 15:12:45 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20AOP=20=EA=B8=B0=EB=B0=98=20=EB=A1=9C?= =?UTF-8?q?=EA=B9=85=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../backend/global/aop/LoggingAspect.java | 34 +++++++++++++ .../global/filter/MDCLoggingFilter.java | 48 +++++++++++++++++++ src/main/resources/logback-spring.xml | 11 ++++- 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/deare/backend/global/aop/LoggingAspect.java create mode 100644 src/main/java/com/deare/backend/global/filter/MDCLoggingFilter.java diff --git a/build.gradle b/build.gradle index af94b27a..e60d0f76 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' diff --git a/src/main/java/com/deare/backend/global/aop/LoggingAspect.java b/src/main/java/com/deare/backend/global/aop/LoggingAspect.java new file mode 100644 index 00000000..599d53ad --- /dev/null +++ b/src/main/java/com/deare/backend/global/aop/LoggingAspect.java @@ -0,0 +1,34 @@ +package com.deare.backend.global.aop; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +@Slf4j +@Aspect +@Component +public class LoggingAspect { + + @Around("execution(* com.deare.backend.api..*Service*.*(..))") + public Object logServiceMethod(ProceedingJoinPoint joinPoint) throws Throwable { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + String className = joinPoint.getTarget().getClass().getSimpleName(); + String methodName = signature.getName(); + + long start = System.currentTimeMillis(); + + try { + Object result = joinPoint.proceed(); + long elapsed = System.currentTimeMillis() - start; + log.info("[{}] {} - {}ms", className, methodName, elapsed); + return result; + } catch (Exception e) { + long elapsed = System.currentTimeMillis() - start; + log.error("[{}] {} - {}ms - 예외: {}", className, methodName, elapsed, e.getMessage()); + throw e; + } + } +} diff --git a/src/main/java/com/deare/backend/global/filter/MDCLoggingFilter.java b/src/main/java/com/deare/backend/global/filter/MDCLoggingFilter.java new file mode 100644 index 00000000..e2641d44 --- /dev/null +++ b/src/main/java/com/deare/backend/global/filter/MDCLoggingFilter.java @@ -0,0 +1,48 @@ +package com.deare.backend.global.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.MDC; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.UUID; + +@Component +public class MDCLoggingFilter extends OncePerRequestFilter { + + private static final String REQUEST_ID = "requestId"; + private static final String USER_ID = "userId"; + private static final String METHOD = "method"; + private static final String URI = "uri"; + + @Override + protected void doFilterInternal( + HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain + ) throws ServletException, IOException { + + try { + MDC.put(REQUEST_ID, UUID.randomUUID().toString().substring(0, 8)); + MDC.put(METHOD, request.getMethod()); + MDC.put(URI, request.getRequestURI()); + + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null && auth.getPrincipal() instanceof Long userId) { + MDC.put(USER_ID, String.valueOf(userId)); + } else { + MDC.put(USER_ID, "anonymous"); + } + + filterChain.doFilter(request, response); + } finally { + MDC.clear(); + } + } +} diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index c17a8455..e0abdf4e 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -3,7 +3,16 @@ - + + + + + + ${LOG_PATTERN} + UTF-8 + +