Skip to content

Conversation

@dahyun24
Copy link
Contributor

@dahyun24 dahyun24 commented Nov 26, 2025

🔗 연관된 이슈

🚀 변경 유형

  • ✨ 기능 추가 (feature)
  • 🐛 버그 수정 (fix)
  • 📝 문서 변경 (docs)
  • ♻️ 리팩토링 (refactor)
  • 🧪 테스트 추가 / 수정 (test)
  • ⚙️ 설정 변경 (chore)

📝 작업 내용

  • 기획에서 요구한 서비스 운영 지표 수집을 위한 로그 추가

현재 작업은 두가지 방법으로 진행했습니다.

  1. 서비스 운영 지표 분석에 필요한 로그의 경우 [STAT] MDC를 추가해서 추후 분석을 용이하도록 설정하였습니다.
  2. 이외의 로그에 대해서는 @Slf4j 를 사용했습니다.

📷 스크린샷

스크린샷 2025-11-27 오전 1 44 37

💬 리뷰 요구사항

📜 리뷰 규칙

Reviewer는 아래 P5 Rule을 참고하여 리뷰를 진행합니다.
P5 Rule을 통해 Reviewer는 Reviewee에게 리뷰의 의도를 보다 정확히 전달할 수 있습니다.

  • P1: 꼭 반영해주세요 (Comment)
  • P2: 적극적으로 고려해주세요 (Comment)
  • P3: 웬만하면 반영해 주세요 (Comment)
  • P4: 반영해도 좋고 넘어가도 좋습니다 (Approve)
  • P5: 그냥 사소한 의견입니다 (Approve)

Summary by CodeRabbit

릴리스 노트

  • Chores
    • 앨범 생성·열람·참여, 인증(토큰 교환·재발급·로그아웃), 사진 업로드 완료·다운로드, Cheese4cut 최종화 관련 이벤트 로깅 추가
    • 별도 로깅 컴포넌트(앨범/사진 통계 로거) 도입으로 로그 형식과 컨텍스트 정비
    • 사용되지 않는 임포트 제거

✏️ Tip: You can customize this high-level summary in your review settings.

@dahyun24 dahyun24 self-assigned this Nov 26, 2025
@dahyun24 dahyun24 added the ✨feature New feature or request label Nov 26, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Walkthrough

앨범 및 사진 관련 서비스들에 구조화된 통계 로깅 컴포넌트(AlbumLogger, PhotoLogger)를 추가하고, AlbumService/PhotoService/PhotoCallbackService/AuthService/Cheese4cutService에 로깅 호출 및 @Slf4j 도입을 적용하며, 일부 DTO 파일의 불필요한 import를 제거했습니다.

Changes

Cohort / File(s) 변경 요약
AlbumLogger 신규 컴포넌트
src/main/java/com/cheeeese/album/application/logger/AlbumLogger.java
앨범 이벤트(stat) 로깅용 Spring 컴포넌트 추가. logAlbumCreated, logAlbumJoined, logAlbumViewed 메서드와 MDC 기반 컨텍스트 설정/해제 구현
AlbumService 로깅 통합
src/main/java/com/cheeeese/album/application/AlbumService.java
AlbumLogger 주입 및 앨범 생성/입장 흐름에서 albumCreated / albumJoined / albumViewed 호출 추가 (기존 로직은 유지)
PhotoLogger 신규 컴포넌트
src/main/java/com/cheeeese/photo/application/logger/PhotoLogger.java
사진 업로드/다운로드 이벤트 로깅용 Spring 컴포넌트 추가. logUploadCompleted, logDownload 및 MDC 처리 구현
PhotoService 로깅 통합
src/main/java/com/cheeeese/photo/application/PhotoService.java
@Slf4j 추가, PhotoLogger 주입. presigned URL 생성 후 요약 로깅 및 다운로드 시 photoLogger.logDownload 호출 추가
PhotoCallbackService 로깅 통합
src/main/java/com/cheeeese/photo/application/PhotoCallbackService.java
PhotoLogger 주입 및 업로드 완료 처리 시 photoLogger.logUploadCompleted 호출 추가
AuthService 로깅 추가
src/main/java/com/cheeeese/auth/application/AuthService.java
@Slf4j 추가 및 토큰 교환/재발급/로그아웃 성공 경로에 user_id 컨텍스트 로그 추가
Cheese4cutService 로깅 추가
src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java
@Slf4j 추가 및 finalizeCheese4cut 완료 이벤트(album_id, maker_id, photo_ids, finalized_at) 로깅 추가
미사용 import 제거
src/main/java/com/cheeeese/album/dto/response/ClosedAlbumSummaryResponse.java, src/main/java/com/cheeeese/album/dto/response/OpenAlbumSummaryResponse.java
com.fasterxml.jackson.annotation.JsonInclude 불필요 import 제거

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant AlbumService
  participant AlbumLogger
  Note over AlbumService,AlbumLogger: 앨범 생성/입장 흐름 (변경: 통계 로깅 추가)
  User->>AlbumService: createAlbum / enterAlbum 요청
  AlbumService->>AlbumService: 비즈니스 로직 수행 (생성/조회/참여 판단)
  alt 새 앨범 생성
    AlbumService->>AlbumLogger: logAlbumCreated(userId, albumCode, expectedParticipant)
  else 기존 앨범 재진입
    AlbumService->>AlbumLogger: logAlbumViewed(userId, albumCode, role)
  end
  alt 새로 입장하거나 참여한 경우
    AlbumService->>AlbumLogger: logAlbumJoined(userId, albumCode, photoExistOnJoin)
  end
  AlbumService-->>User: 응답 반환
Loading
sequenceDiagram
  autonumber
  participant User
  participant PhotoService
  participant PhotoLogger
  Note over PhotoService,PhotoLogger: 업로드 완료 및 다운로드 로깅
  User->>PhotoService: presigned URL 요청 / 다운로드 요청
  PhotoService->>PhotoService: presigned URL 생성 / 다운로드 URL 조회
  alt presigned 생성
    PhotoService->>PhotoService: 로그 info(요약)
  end
  alt 다운로드 요청
    PhotoService->>PhotoLogger: logDownload(userId, albumCode, photoIds)
  end
  PhotoService-->>User: URL 반환
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 주의 깊게 검토할 영역:
    • MDC 키 설정/해제의 finally 블록 정상 동작 여부 (AlbumLogger, PhotoLogger)
    • 전달되는 필드의 정확성(예: album_joined의 is_first_join 하드코딩)
    • @Slf4j 도입으로 기존 로그와 충돌 가능성(포맷/컨텍스트)
    • 로깅 호출이 트랜잭션/예외 경로에 미치는 영향

Possibly related PRs

Suggested reviewers

  • zyovn

Poem

🐰 통계로 깡총깡총 뛰며
앨범과 사진 발자국을 새기네
MDC 꽃 달고
조용히 기록을 남기며 📜
코드 숲에 햇살 같은 로그를 남기노라

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 풀 리퀘스트 제목이 변경 내용의 주요 목표를 명확하게 반영하고 있습니다. 제목은 '서비스 운영 핵심 지표 수집을 위한 비즈니스 로그 추가'로, 실제 변경 내용(AlbumLogger, PhotoLogger, AuthService, Cheese4cutService 등에 로그 추가)과 일치합니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#100-logs

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41fb546 and acc5876.

📒 Files selected for processing (1)
  • src/main/java/com/cheeeese/album/application/AlbumService.java (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-26T16:49:59.252Z
Learnt from: dahyun24
Repo: Say-Cheeeese/BE PR: 104
File: src/main/java/com/cheeeese/album/application/logger/AlbumLogger.java:37-37
Timestamp: 2025-11-26T16:49:59.252Z
Learning: In AlbumLogger.java, the method logAlbumJoined() hardcodes is_first_join=true because it is only called when a new user joins an album for the first time, not for re-visits.

Applied to files:

  • src/main/java/com/cheeeese/album/application/AlbumService.java
🔇 Additional comments (4)
src/main/java/com/cheeeese/album/application/AlbumService.java (4)

3-3: LGTM! AlbumLogger 의존성 추가가 적절합니다.

Spring DI 패턴을 올바르게 따르고 있으며, 구조화된 로깅 컴포넌트 통합이 깔끔하게 처리되었습니다.

Also applies to: 68-69


101-101: LGTM! 앨범 생성 로그 호출 위치가 적절합니다.

모든 DB 작업(앨범 저장, 사용자-앨범 관계 저장, 카운트 증가, Redis 등록)이 완료된 후 로그를 기록하여 데이터 일관성을 보장하고 있습니다.


132-134: LGTM! 재방문 로그 기록이 정확합니다.

기존 참여자의 재방문 케이스를 정확히 포착하고 있으며, 사용자 역할 정보를 함께 로깅하여 분석에 유용한 컨텍스트를 제공합니다.


161-163: LGTM! 신규 참여 로그 기록이 정확합니다.

참여 시점의 사진 존재 여부(photoExist)를 정확히 계산하여 로깅하고 있어, 신규 참여자의 첫 경험 분석에 유용한 데이터를 제공합니다.


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: 2

🧹 Nitpick comments (5)
src/main/java/com/cheeeese/auth/application/AuthService.java (1)

50-87: 성공 케이스 로깅 포맷/용도 정리 제안 (P3)

exchangeTempCode, reissueToken, logout 3곳의 성공 로그 추가 자체는 운영 관점에서 매우 유용해 보입니다. 다만 PR 설명에 “운영 지표용 로그는 MDC에 [STAT] 키를 추가”한다고 되어 있어서, 이 세 로그가 운영 지표 대상인지, 단순 기능 로그인지를 한 번 정리해 보시면 좋겠습니다.

제안 사항 (P3: 웬만하면 반영 권장):

  1. 운영 지표용이라면 MDC [STAT] 적용 검토

    • 다른 모듈(AlbumLogger, PhotoLogger 등)에서 STAT 로그를 MDC로 태깅하고 있다면,
      이 세 이벤트(토큰 교환/재발급/로그아웃 성공)도 같은 방식으로 태깅하면
      검색/집계 시 일관성이 높아질 것 같습니다.
    • 예: MDC.put("[STAT]", "AUTH_TOKEN_EXCHANGE_SUCCESS"); 등으로 태깅 후 log.info(...).
  2. 로그 메시지 키-값 형태 표준화

    • 현재: "[AUTH] Token Exchange Success | user_id={}" 형태의 자유 텍스트.
    • 후처리/집계를 염두에 두면 아래처럼 key=value 포맷을 쓰는 것도 고려해볼 만합니다.
      • 예: "[AUTH] event=token_exchange result=success user_id={}",
        "[AUTH] event=token_reissue result=success user_id={}",
        "[AUTH] event=logout result=success user_id={}".
    • 이렇게 맞춰두면 나중에 로그 파이프라인에서 파싱하기 훨씬 수월합니다.
  3. 로그 레벨/양에 대한 간단한 점검

    • Auth 관련 엔드포인트는 트래픽이 많은 편일 수 있어서,
      모든 성공 케이스를 INFO로 남기면 로그량/비용이 커질 수 있습니다.
    • 만약 이 로그들이 “정말 운영 지표 집계용 핵심 로그”라면 INFO 유지가 맞고,
      아니라면 별도의 STAT 전용 로거나 샘플링/레벨 조정도 장기적으로 고려할 수 있겠습니다.

현재 구현은 기능적으로 문제 없고, 토큰 값도 로그에 노출하지 않아 보안상으로도 안전해 보입니다. 위 내용은 주로 “지표/분석 용이성”과 “일관성” 관점에서의 제안입니다.

src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java (1)

146-148: 로깅 패턴이 다른 로거들과 일관성이 없습니다.

AlbumLoggerPhotoLogger[STAT] prefix와 MDC 컨텍스트를 사용하는 반면, 이 로그는 [Cheese4cut] prefix를 사용하고 MDC 설정이 없습니다. 분석 파이프라인에서 일관된 처리를 위해 Cheese4cutLogger 컴포넌트를 생성하거나 기존 패턴을 따르는 것이 좋습니다.

-log.info("[Cheese4cut] Cheese4cut Finalized | album_id={} maker_id={} photo_ids={} finalized_at={}",
-        album.getId(), user.getId(), request.photoIds(), LocalDateTime.now());
+log.info("[STAT] cheese4cut_finalized | album_id={} maker_id={} photo_ids={} finalized_at={}",
+        album.getId(), user.getId(), request.photoIds(), LocalDateTime.now());

또는 Cheese4cutLogger 컴포넌트를 별도로 생성하여 MDC 컨텍스트와 함께 사용하는 것을 고려해주세요.

src/main/java/com/cheeeese/photo/application/PhotoService.java (1)

95-97: 업로드 요청 로그가 PhotoLogger 패턴을 따르지 않습니다.

다운로드 로그(Line 128)는 PhotoLogger를 사용하여 [STAT] prefix와 MDC 컨텍스트를 설정하지만, 업로드 요청 로그는 직접 log.info를 사용하고 [Photo] prefix를 사용합니다. 통계 분석 파이프라인에서 일관된 처리를 위해 PhotoLogger에 업로드 요청용 메서드를 추가하는 것을 고려해주세요.

src/main/java/com/cheeeese/album/application/logger/AlbumLogger.java (2)

1-14: 클래스 구조와 설정이 적절합니다.

로깅 컴포넌트로서의 기본 구조가 잘 설계되었습니다. MDC를 활용한 구조화된 로깅 접근 방식도 좋습니다.

다만, MDC 키로 사용되는 "type"이 다소 일반적이어서 애플리케이션의 다른 부분과 충돌할 가능성이 있습니다. "log_type" 또는 "event_type" 같은 보다 구체적인 이름을 고려해보세요.


20-56: P4: MDC 설정/정리 패턴의 중복 제거를 고려해보세요.

세 메서드 모두 동일한 MDC 설정 및 정리 패턴을 반복하고 있습니다. 헬퍼 메서드를 도입하면 코드 중복을 줄이고 유지보수성을 향상시킬 수 있습니다.

예시:

private void executeWithMDC(String eventType, Runnable loggingAction) {
    try {
        MDC.put("type", eventType);
        loggingAction.run();
    } finally {
        MDC.remove("type");
    }
}

public void logAlbumCreated(Long userId, String albumCode, int expectedParticipant) {
    executeWithMDC("album", () -> 
        log.info("{} album_created | user_id={} album_code={} expected_participant={} created_at={}",
                STAT_PREFIX, userId, albumCode, expectedParticipant, LocalDateTime.now())
    );
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbbf86a and 41fb546.

📒 Files selected for processing (9)
  • src/main/java/com/cheeeese/album/application/AlbumService.java (5 hunks)
  • src/main/java/com/cheeeese/album/application/logger/AlbumLogger.java (1 hunks)
  • src/main/java/com/cheeeese/album/dto/response/ClosedAlbumSummaryResponse.java (0 hunks)
  • src/main/java/com/cheeeese/album/dto/response/OpenAlbumSummaryResponse.java (0 hunks)
  • src/main/java/com/cheeeese/auth/application/AuthService.java (4 hunks)
  • src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java (2 hunks)
  • src/main/java/com/cheeeese/photo/application/PhotoCallbackService.java (3 hunks)
  • src/main/java/com/cheeeese/photo/application/PhotoService.java (6 hunks)
  • src/main/java/com/cheeeese/photo/application/logger/PhotoLogger.java (1 hunks)
💤 Files with no reviewable changes (2)
  • src/main/java/com/cheeeese/album/dto/response/ClosedAlbumSummaryResponse.java
  • src/main/java/com/cheeeese/album/dto/response/OpenAlbumSummaryResponse.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-13T12:56:22.161Z
Learnt from: dahyun24
Repo: Say-Cheeeese/BE PR: 58
File: src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java:149-156
Timestamp: 2025-11-13T12:56:22.161Z
Learning: In src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java, the finalizeCheese4cut method intentionally re-sorts photos using findAllByIdInOrderByLikesDescCreatedDesc(request.photoIds()) instead of preserving the client's requested order. This is a defensive measure to ensure photos are always ordered by likes (DESC) and creation time (DESC), regardless of what order the client sends, preventing incorrect ordering from client errors.

Applied to files:

  • src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java
  • src/main/java/com/cheeeese/photo/application/PhotoService.java
  • src/main/java/com/cheeeese/photo/application/PhotoCallbackService.java
📚 Learning: 2025-10-31T13:17:52.523Z
Learnt from: dahyun24
Repo: Say-Cheeeese/BE PR: 35
File: src/main/java/com/cheeeese/photo/application/PhotoService.java:46-52
Timestamp: 2025-10-31T13:17:52.523Z
Learning: In src/main/java/com/cheeeese/photo/application/PhotoService.java, the getRecentThumbnailUrls method intentionally returns only the first thumbnail URL when photos.size() < 5, rather than returning all available thumbnails. This is according to product requirements: 0 photos → empty list, 1-4 photos → single thumbnail (most recent), 5 photos → all 5 thumbnails.

Applied to files:

  • src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java
  • src/main/java/com/cheeeese/photo/application/PhotoService.java
  • src/main/java/com/cheeeese/photo/application/PhotoCallbackService.java
🧬 Code graph analysis (1)
src/main/java/com/cheeeese/cheese4cut/application/Cheese4cutService.java (2)
src/main/java/com/cheeeese/album/application/AlbumService.java (1)
  • Slf4j (51-324)
src/main/java/com/cheeeese/album/application/AlbumExpirationService.java (1)
  • Slf4j (24-81)
🔇 Additional comments (7)
src/main/java/com/cheeeese/auth/application/AuthService.java (1)

23-31: 클래스 레벨 @slf4j 추가 방향 👍 (P4)

서비스 레벨에서 공통 로거를 쓰도록 @slf4j 추가한 부분은 PR 목적(운영 지표 및 비즈니스 로그 추가)에 잘 맞고, 별다른 부작용도 없어 보입니다. 이 상태 그대로 사용해도 될 것 같습니다.

src/main/java/com/cheeeese/photo/application/PhotoCallbackService.java (1)

56-62: albumCode가 null일 경우 로그에 null이 기록됩니다.

현재 photoLogger.logUploadCompleted()albumCode null 체크 이전에 호출되고 있습니다. albumCode가 null인 경우에도 로그가 기록되어야 하는지, 아니면 null 체크 이후로 이동해야 하는지 확인이 필요합니다.

 String albumCode = photoRepository.findAlbumCodeByPhotoId(request.photoId());

-photoLogger.logUploadCompleted(photo.getUser().getId(), albumCode, photo.getId());
-
 if (albumCode != null) {
+    photoLogger.logUploadCompleted(photo.getUser().getId(), albumCode, photo.getId());
     photoQueryService.invalidatePhotoCache(albumCode);
 }
src/main/java/com/cheeeese/photo/application/PhotoService.java (1)

128-129: LGTM!

다운로드 로깅이 적절한 위치에서 PhotoLogger를 사용하여 일관된 패턴으로 구현되었습니다.

src/main/java/com/cheeeese/album/application/AlbumService.java (3)

68-69: LGTM!

앨범 생성 로깅이 적절한 위치에서 AlbumLogger를 사용하여 일관된 패턴으로 구현되었습니다.

Also applies to: 99-99


130-132: LGTM!

기존 참여자의 재방문 로깅이 적절하게 구현되었습니다.


159-161: LGTM!

신규 참여자 입장 로깅이 적절하게 구현되었습니다. photoExist 플래그를 통해 사진 존재 여부도 함께 기록됩니다.

src/main/java/com/cheeeese/photo/application/logger/PhotoLogger.java (1)

10-43: LGTM!

PhotoLogger 컴포넌트가 AlbumLogger와 일관된 패턴으로 잘 구현되었습니다. MDC 컨텍스트 설정과 finally 블록을 통한 정리가 적절합니다.

Copy link
Member

@zyovn zyovn left a comment

Choose a reason for hiding this comment

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

수고하셧습니다잇

image

@dahyun24 dahyun24 merged commit 29a0e82 into develop Nov 26, 2025
1 check passed
@zyovn zyovn deleted the feat/#100-logs branch November 26, 2025 17:27
@dahyun24 dahyun24 linked an issue Nov 27, 2025 that may be closed by this pull request
@coderabbitai coderabbitai bot mentioned this pull request Jan 5, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 서비스 운영 지표를 위한 로그 수집

3 participants