Skip to content

Conversation

@whqtker
Copy link
Member

@whqtker whqtker commented Feb 1, 2026

관련 이슈

작업 내용

채팅 관련 QA를 진행하는데, STOMP 프레임이 로깅되지 않아 동작을 제대로 확인하기 어려웠습니다.

이에 STOMP 프레임을 로깅하는 인터셉터를 작성했습니다.
dev 프로파일인 경우에만 동작하도록 구현했습니다. prod 프로파일에서도 로깅하면 사용자 채팅 등이 로깅될 수 있기에, 보안 상의 문제가 있을 거라도 판단했습니다.
선택적으로 인터셉터를 스프링 컨테이너에 등록하기에, Optional 로 주입했고 ifPresent 로 처리하게끔 구현했습니다.

특이 사항

리뷰 요구사항 (선택)

@coderabbitai
Copy link

coderabbitai bot commented Feb 1, 2026

Walkthrough

이 변경사항은 WebSocket 통신 로깅을 위한 새로운 인터셉터 기능을 추가합니다. 다음과 같이 구성됩니다:

  1. WebSocketLoggingInterceptor 컴포넌트 신규 추가

    • Dev 프로필에서만 활성화되는 Spring 컴포넌트
    • ChannelInterceptor를 구현하여 STOMP WebSocket 라이프사이클 이벤트 추적
    • CONNECT, SUBSCRIBE, SEND, DISCONNECT 커맨드에 대해 사용자 ID와 함께 로깅 수행
  2. StompWebSocketConfig 수정

    • Optional 타입의 WebSocketLoggingInterceptor 의존성 추가
    • configureClientInboundChannel 메서드에서 인터셉터가 존재하면 먼저 등록하는 조건부 로직 구현
    • 기존 로직 변경 없이 확장 가능한 형태로 설계

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • wibaek
  • lsy1307
  • Gyuhyeok99
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목 'feat: WebSocket 로깅 인터셉터 작성'은 PR의 주요 변경 사항인 WebSocket 로깅 인터셉터 추가를 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명은 관련 이슈, 작업 내용(STOMP 프레임 로깅 구현 및 dev 프로파일 제한), Optional 주입 방식을 포함하여 대부분 템플릿을 따르고 있습니다.
Linked Issues check ✅ Passed PR은 이슈 #634에서 요구한 WebSocket(STOMP) 프레임 로깅 인터셉터를 성공적으로 구현했으며, dev 프로파일 제한과 Optional 주입 방식으로 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 코드 변경사항은 WebSocket 로깅 인터셉터 추가와 이를 StompWebSocketConfig에 통합하는 범위 내 작업으로, 이슈 #634의 목표와 일치하며 범위를 벗어난 변경사항이 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/main/java/com/example/solidconnection/chat/config/WebSocketLoggingInterceptor.java`:
- Around line 45-52: In extractUserId, avoid potential NPE/ClassCastException by
fetching tokenAuth.getPrincipal() into a local variable, check that it is
non-null and an instance of SiteUserDetails before casting, and only then call
getSiteUser().getId(); if the principal is null or not a SiteUserDetails, return
null. Update the method (referencing extractUserId,
TokenAuthentication.getPrincipal, and SiteUserDetails) to perform these safe
null/instance checks and short-circuit to null for invalid cases.

Comment on lines +45 to +52
private Long extractUserId(StompHeaderAccessor accessor) {
Principal user = accessor.getUser();
if (user instanceof TokenAuthentication tokenAuth) {
SiteUserDetails details = (SiteUserDetails) tokenAuth.getPrincipal();
return details.getSiteUser().getId();
}
return null;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

extractUserId 메서드에서 잠재적인 NPE 및 ClassCastException 위험이 있습니다.

  1. TokenAuthentication.getPrincipal()Object 타입을 반환하며, 인증되지 않은 상태에서는 null을 반환할 수 있습니다 (관련 코드 TokenAuthentication 생성자 참조).
  2. getPrincipal()null이거나 SiteUserDetails 타입이 아닌 경우, 직접 캐스팅 시 예외가 발생합니다.
🐛 안전한 타입 체크를 추가한 수정 제안
     private Long extractUserId(StompHeaderAccessor accessor) {
         Principal user = accessor.getUser();
-        if (user instanceof TokenAuthentication tokenAuth) {
-            SiteUserDetails details = (SiteUserDetails) tokenAuth.getPrincipal();
-            return details.getSiteUser().getId();
+        if (user instanceof TokenAuthentication tokenAuth
+                && tokenAuth.getPrincipal() instanceof SiteUserDetails details) {
+            return details.getSiteUser().getId();
         }
         return null;
     }
🤖 Prompt for AI Agents
In
`@src/main/java/com/example/solidconnection/chat/config/WebSocketLoggingInterceptor.java`
around lines 45 - 52, In extractUserId, avoid potential NPE/ClassCastException
by fetching tokenAuth.getPrincipal() into a local variable, check that it is
non-null and an instance of SiteUserDetails before casting, and only then call
getSiteUser().getId(); if the principal is null or not a SiteUserDetails, return
null. Update the method (referencing extractUserId,
TokenAuthentication.getPrincipal, and SiteUserDetails) to perform these safe
null/instance checks and short-circuit to null for invalid cases.

Copy link
Contributor

@sukangpunch sukangpunch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!! 궁금한 점 리뷰 달았습니다

public void configureClientInboundChannel(ChannelRegistration registration) {
InboundProperties inboundProperties = stompProperties.threadPool().inbound();
registration.interceptors(stompHandler).taskExecutor().corePoolSize(inboundProperties.corePoolSize()).maxPoolSize(inboundProperties.maxPoolSize()).queueCapacity(inboundProperties.queueCapacity());
webSocketLoggingInterceptor.ifPresent(registration::interceptors);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 인터셉터 등록 순서 문제는 발생하지 않나요?
StompHandler 보다 이전에 로깅 인터셉터가 등록 되었을 때, User Principal 을 잘 가져올 수 있는지 궁금합니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: WebSocket 로깅 인터셉터 작성

2 participants