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"/>