diff --git a/src/main/java/org/runnect/server/common/resolver/userId/UserIdResolver.java b/src/main/java/org/runnect/server/common/resolver/userId/UserIdResolver.java
index 55770c6..cedff32 100644
--- a/src/main/java/org/runnect/server/common/resolver/userId/UserIdResolver.java
+++ b/src/main/java/org/runnect/server/common/resolver/userId/UserIdResolver.java
@@ -4,6 +4,7 @@
import org.runnect.server.common.constant.TokenStatus;
import org.runnect.server.common.constant.ErrorStatus;
import lombok.RequiredArgsConstructor;
+import org.slf4j.MDC;
import org.runnect.server.common.module.check.TypeChecker;
import org.runnect.server.user.exception.authException.InvalidAccessTokenException;
import org.runnect.server.user.exception.authException.NullAccessTokenException;
@@ -76,6 +77,7 @@ public Object resolveArgument(@NotNull MethodParameter parameter, ModelAndViewCo
&& request.getMethod().equals("GET")
&& VISITOR_POSSIBLE_URLS.contains(removeLastPathSegment(request.getRequestURI()))){
// 방문자모드 허용 api에 대한 요청이 맞는지 검증
+ MDC.put("userId", String.valueOf(VISITOR_ID));
return VISITOR_ID;
}
@@ -92,7 +94,9 @@ public Object resolveArgument(@NotNull MethodParameter parameter, ModelAndViewCo
final String tokenContents = jwtService.getJwtContents(accessToken);
try {
- return Long.parseLong(tokenContents);
+ Long userId = Long.parseLong(tokenContents);
+ MDC.put("userId", String.valueOf(userId));
+ return userId;
} catch (NumberFormatException e) {
throw new NotFoundUserException(ErrorStatus.NOT_FOUND_USER_EXCEPTION, ErrorStatus.NOT_FOUND_USER_EXCEPTION.getMessage());
}
diff --git a/src/main/java/org/runnect/server/config/logging/MdcLoggingFilter.java b/src/main/java/org/runnect/server/config/logging/MdcLoggingFilter.java
index d7fe4a3..9d90126 100644
--- a/src/main/java/org/runnect/server/config/logging/MdcLoggingFilter.java
+++ b/src/main/java/org/runnect/server/config/logging/MdcLoggingFilter.java
@@ -1,6 +1,9 @@
package org.runnect.server.config.logging;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.runnect.server.common.constant.TokenStatus;
+import org.runnect.server.config.jwt.JwtService;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
@@ -17,13 +20,21 @@
* 요청마다 traceId를 발급해 MDC에 담아둔다.
* 로그 패턴에 %X{traceId}를 포함시키면(logback-spring.xml), 여러 요청이 뒤섞인 로그에서도
* 같은 traceId로 특정 요청의 흐름만 추적할 수 있다.
+ *
+ * userId는 @UserId 파라미터가 없는 요청(토큰 재발급, 배너 등)에서도 로그에 남도록
+ * 여기서 best-effort로 한 번 더 채운다. 실제 인증 검증/방문자 모드 처리는 UserIdResolver가
+ * 맡고, 그 결과가 이후 이 값을 덮어쓴다.
*/
@Slf4j
@Component
+@RequiredArgsConstructor
public class MdcLoggingFilter implements Filter {
private static final String TRACE_ID_KEY = "traceId";
private static final int TRACE_ID_LENGTH = 8;
+ private static final String USER_ID_KEY = "userId";
+
+ private final JwtService jwtService;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
@@ -32,10 +43,26 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
try {
MDC.put(TRACE_ID_KEY, traceId);
HttpServletRequest httpRequest = (HttpServletRequest) request;
+ populateUserIdBestEffort(httpRequest);
log.info("{} {}", httpRequest.getMethod(), httpRequest.getRequestURI());
chain.doFilter(request, response);
} finally {
MDC.remove(TRACE_ID_KEY);
+ MDC.remove(USER_ID_KEY);
+ }
+ }
+
+ private void populateUserIdBestEffort(HttpServletRequest request) {
+ String accessToken = request.getHeader("accessToken");
+ if (accessToken == null) {
+ return;
+ }
+ try {
+ if (jwtService.verifyToken(accessToken) == TokenStatus.TOKEN_VALID) {
+ MDC.put(USER_ID_KEY, jwtService.getJwtContents(accessToken));
+ }
+ } catch (RuntimeException e) {
+ // 로깅 목적의 best-effort 파싱이므로 실패해도 요청 처리는 계속 진행한다.
}
}
}
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
index 81b0490..3a1dba5 100644
--- a/src/main/resources/logback-spring.xml
+++ b/src/main/resources/logback-spring.xml
@@ -3,7 +3,7 @@
+ value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] [userId=%X{userId}] %-5level [%thread] %logger{36} - %msg%n"/>