Skip to content

Conversation

@LEEJaeHyeok97
Copy link
Member

@LEEJaeHyeok97 LEEJaeHyeok97 commented May 11, 2025

관련 이슈

close #69

주요 변경 사항

주요 변경 사항에 대해 작성해주세요.

  • @PageViewed 애노테이션 정의 및 AOP 적용을 통한 비즈니스 메트릭 수집 기능 구현
  • PageViewAspect를 통해 커스텀 AOP 로직 작성 및 Prometheus 카운터 연동
  • 카페 조회 API에 커스텀 어노테이션 적용
  • CafeConfig.kt 추가로 관련 빈 설정 분리

기타

고려해야 하는 내용을 작성해 주세요.

모니터링용 서버를 분리하는게 더 나을지 고민 중입니다.
추후 @PageViewed를 다른 API에도 확장 적용 가능

Summary by CodeRabbit

  • 신규 기능

    • 페이지별 조회 수를 집계하는 기능이 추가되었습니다. 각 카페 관련 API 호출 시 페이지별 조회 수가 자동으로 기록됩니다.
    • 카페 목록 조회 API 호출 횟수를 자동으로 집계하는 기능이 도입되었습니다.
    • Prometheus 및 Spring Actuator 기반의 모니터링 및 메트릭 수집 기능이 추가되었습니다.
  • 환경설정

    • 환경별(local, prod) 설정 파일이 .gitignore에 추가되어 버전 관리에서 제외됩니다.
    • 빌드 정보 메타데이터가 자동 생성됩니다.
  • 버그 수정

    • API 예외 처리 범위가 카페 관련 컨트롤러로 한정되었습니다.

@LEEJaeHyeok97 LEEJaeHyeok97 requested a review from kssumin May 11, 2025 11:27
@LEEJaeHyeok97 LEEJaeHyeok97 self-assigned this May 11, 2025
@LEEJaeHyeok97 LEEJaeHyeok97 added the ✨ feature New feature or request label May 11, 2025
@LEEJaeHyeok97 LEEJaeHyeok97 linked an issue May 11, 2025 that may be closed by this pull request
4 tasks
@coderabbitai
Copy link

coderabbitai bot commented May 11, 2025

Walkthrough

모니터링 기능 도입을 위해 Prometheus 및 Micrometer 기반의 메트릭 수집 기능이 추가되었습니다. 주요 API 엔드포인트에 페이지 뷰 카운트와 카운터 메트릭이 적용되었으며, 관련 의존성 및 AOP 구성, 환경설정 파일 무시 규칙이 확장되었습니다. Kafka 및 CQRS 관련 사항은 포함되지 않았습니다.

Changes

파일/경로 변경 요약
.gitignore 환경별 application 설정 파일(application-local.yml, application-prod.yml) 무시 규칙 추가
build.gradle.kts
buildSrc/src/main/kotlin/Dependency.kt
Spring Actuator, Prometheus 의존성 추가, buildInfo() 설정 추가
src/main/kotlin/com/coffee/api/common/aop/PageViewed.kt
src/main/kotlin/com/coffee/api/common/aop/PageViewAspect.kt
페이지 뷰 측정용 커스텀 애노테이션 및 AOP Aspect 신규 추가
src/main/kotlin/com/coffee/api/cafe/presentation/adapter/in/restapi/CafeController.kt 모든 엔드포인트에 @PageViewed 애노테이션 적용
src/main/kotlin/com/coffee/api/cafe/application/CafeService.kt cafe 목록 조회 메서드에 @counted 메트릭 애노테이션 적용
src/main/kotlin/com/coffee/api/config/aop/CafeConfig.kt CountedAspect 빈 등록용 설정 클래스 신규 추가
src/main/kotlin/com/coffee/api/config/ApiControllerAdvice.kt @RestControllerAdvice의 basePackages 속성 지정(적용 범위 제한)

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant CafeController
    participant PageViewAspect
    participant CafeService
    participant MeterRegistry

    Client->>CafeController: findAllCafes() 호출
    CafeController->>PageViewAspect: @PageViewed Advice 실행 (페이지 뷰 카운트)
    PageViewAspect->>MeterRegistry: "page.view.count" 카운터 증가
    CafeController->>CafeService: invoke() 호출
    CafeService->>MeterRegistry: @Counted Advice 실행 ("cafe.find" 카운터 증가)
    CafeService-->>CafeController: 결과 반환
    CafeController-->>Client: 응답 반환
Loading

Assessment against linked issues

Objective Addressed Explanation
Prometheus + Grafana 기반 모니터링 시스템 구성 (#69)
주요 지표 수집 (API 응답 시간, 에러율, 시스템 자원 사용률 등) (#69)
Kafka 환경 구축 및 메시지 송수신 테스트 (#69) Kafka 관련 코드 추가 또는 메시지 송수신 테스트 코드 없음
CQRS 적용을 위한 구조 정리 (#69) CQRS 관련 구조 또는 코드 변경 없음

Suggested reviewers

  • kssumin

Poem

🐰
메트릭 토끼가 뛰노는 들판에
카운터와 페이지 뷰가 새로 심어졌네
Prometheus와 Micrometer가 손을 잡고
카페의 인기와 방문을 숫자로 세네
오늘도 로그밭에 당근 한 개 추가!
🥕

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@LEEJaeHyeok97 LEEJaeHyeok97 changed the title [FEAT] 커스텀 AOP 기반 페이지 조회 메트릭 수집 기능 구현 [FEAT] AOP 기반 페이지 조회 카운터 메트릭 수집 기능 구현 May 11, 2025
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

🧹 Nitpick comments (2)
src/main/kotlin/com/coffee/api/common/aop/PageViewed.kt (1)

1-6: 페이지 조회 추적을 위한 애노테이션 정의가 잘 되었습니다.

PageViewed 애노테이션은 AOP 기반 페이지 조회 메트릭 수집을 위한 적절한 정의입니다. 함수 레벨에 적용되도록 타겟이 설정되었고, 런타임에 사용 가능하도록 유지되며, 페이지명을 지정할 수 있는 name 파라미터를 가지고 있습니다.

한 가지 제안하자면, 가독성과 문서화를 위해 애노테이션에 문서화 주석(KDoc)을 추가하는 것이 좋을 것 같습니다.

 package com.coffee.api.common.aop

+/**
+ * 페이지 조회 메트릭을 수집하기 위한 애노테이션입니다.
+ * 이 애노테이션이 적용된 메소드가 호출될 때마다 해당 페이지의 조회수가 증가합니다.
+ * 
+ * @property name 페이지 식별을 위한 고유한 이름
+ */
 @Target(AnnotationTarget.FUNCTION)
 @Retention(AnnotationRetention.RUNTIME)
 annotation class PageViewed(val name: String)
src/main/kotlin/com/coffee/api/config/aop/CafeConfig.kt (1)

1-14: AOP 메트릭 설정 클래스 구현

메트릭 수집을 위한 AOP 설정 클래스를 구현했습니다. CountedAspect 빈을 등록하여 @Counted 애노테이션이 작동할 수 있도록 설정하였습니다.

다만, 클래스 이름이 CafeConfig보다는 MetricsConfig 또는 MonitoringConfig와 같이 기능을 더 명확하게 나타내는 이름이 좋을 것 같습니다.

-package com.coffee.api.config.aop
+package com.coffee.api.config.aop
 
 import io.micrometer.core.aop.CountedAspect
 import io.micrometer.core.instrument.MeterRegistry
 import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.Configuration
 
 @Configuration
-class CafeConfig {
+class MetricsConfig {
 
     @Bean
     fun countedAspect(registry: MeterRegistry): CountedAspect =
         CountedAspect(registry)
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f0e77e and 87418b5.

📒 Files selected for processing (9)
  • .gitignore (1 hunks)
  • build.gradle.kts (2 hunks)
  • buildSrc/src/main/kotlin/Dependency.kt (1 hunks)
  • src/main/kotlin/com/coffee/api/cafe/application/CafeService.kt (2 hunks)
  • src/main/kotlin/com/coffee/api/cafe/presentation/adapter/in/restapi/CafeController.kt (4 hunks)
  • src/main/kotlin/com/coffee/api/common/aop/PageViewAspect.kt (1 hunks)
  • src/main/kotlin/com/coffee/api/common/aop/PageViewed.kt (1 hunks)
  • src/main/kotlin/com/coffee/api/config/ApiControllerAdvice.kt (1 hunks)
  • src/main/kotlin/com/coffee/api/config/aop/CafeConfig.kt (1 hunks)
🔇 Additional comments (10)
buildSrc/src/main/kotlin/Dependency.kt (1)

18-19: 모니터링 기능을 위한 의존성 추가가 적절합니다.

Spring Actuator와 Prometheus 의존성을 추가하여 페이지 조회 메트릭 수집 기능을 구현하기 위한 기반을 마련했습니다. 이는 PR 목표와 일치하며 모니터링 시스템 구축에 필수적인 요소입니다.

.gitignore (1)

44-46: 환경별 설정 파일 무시 규칙 추가가 적절합니다.

환경별 설정 파일(application.yml, application-local.yml, application-prod.yml)을 Git에서 무시하도록 설정한 것은 보안 및 환경 분리 측면에서 좋은 관행입니다. 환경별 설정에는 모니터링 엔드포인트, 접근 제어 등 민감한 정보가 포함될 수 있으므로 이러한 파일을 버전 관리에서 제외하는 것이 적절합니다.

src/main/kotlin/com/coffee/api/config/ApiControllerAdvice.kt (1)

11-13: 컨트롤러 어드바이스 범위 제한이 적절합니다.

@RestControllerAdvice 애노테이션에 basePackages 속성을 추가하여 특정 패키지(com.coffee.api.cafe.presentation.adapter.in.restapi)에만 적용되도록 제한한 것은 좋은 접근 방식입니다. 이렇게 하면 해당 패키지의 컨트롤러에만 예외 처리가 적용되어 다른 패키지의 컨트롤러와 충돌할 가능성이 줄어듭니다.

다만, 나중에 다른 패키지에도 이 어드바이스를 적용해야 할 경우 확장이 필요할 수 있으니 참고하시기 바랍니다.

src/main/kotlin/com/coffee/api/cafe/presentation/adapter/in/restapi/CafeController.kt (3)

11-11: 적절한 커스텀 애노테이션 가져오기

PageViewed 애노테이션을 적절하게 가져왔습니다. 이 애노테이션은 컨트롤러 메서드에 페이지 조회 메트릭을 적용하기 위한 용도로 가져와졌습니다.


29-29: 페이지 뷰 측정 애노테이션 적용

카페 목록 조회 API에 @PageViewed("cafe_list") 애노테이션을 추가하여 페이지 조회 메트릭을 수집할 수 있도록 하였습니다. 이름이 명확하게 지정되어 메트릭 식별이 용이합니다.


40-40: 일관된 페이지 뷰 메트릭 구현

모든 주요 엔드포인트에 @PageViewed 애노테이션을 일관되게 적용하여 엔드포인트별 페이지 조회수를 추적할 수 있도록 구현하였습니다. API 엔드포인트의 목적에 맞게 태그 이름을 지정하여 메트릭의 가독성이 좋습니다.

Also applies to: 50-50, 57-57

src/main/kotlin/com/coffee/api/cafe/application/CafeService.kt (2)

6-6: Micrometer 의존성 추가

메트릭 수집을 위한 Micrometer의 Counted 애노테이션을 적절하게 가져왔습니다.


16-16: 서비스 메서드 호출 카운터 구현

@Counted 애노테이션을 사용하여 카페 목록 조회 서비스 메서드의 호출 횟수를 추적하는 메트릭을 구현했습니다. 메트릭 이름과 설명이 명확하여 모니터링 대시보드에서 식별하기 쉽습니다.

build.gradle.kts (2)

83-87: 모니터링 관련 의존성 추가

Spring Actuator와 Prometheus 의존성을 추가하여 애플리케이션 모니터링 및 메트릭 수집을 지원하도록 구성했습니다. 의존성을 명확하게 구분하여 추가한 점이 좋습니다.


127-129: Spring Boot 빌드 정보 활성화

springBoot.buildInfo() 설정을 추가하여 빌드 메타데이터 정보를 생성하도록 했습니다. 이는 Actuator의 info 엔드포인트를 통해 빌드 정보를 확인할 수 있게 해주어 유용합니다.

Comment on lines +1 to +24
package com.coffee.api.common.aop

import io.micrometer.core.instrument.MeterRegistry
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.springframework.stereotype.Component

@Aspect
@Component
class PageViewAspect(
private val meterRegistry: MeterRegistry
) {

@Before("@annotation(pageViewed)")
fun countPageView(joinPoint: JoinPoint, pageViewed: PageViewed) {
val counterName = "page.view.count"
val tagName = pageViewed.name

meterRegistry
.counter(counterName, "page", tagName)
.increment()
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

페이지 뷰 측정을 위한 AOP 구현

페이지 뷰 메트릭을 수집하기 위한 AOP 클래스를 구현했습니다. @PageViewed 애노테이션이 적용된 메서드 실행 전에 메트릭을 증가시키는 방식으로 구현되었습니다.

하지만 몇 가지 개선할 점이 있습니다:

  1. 에러 처리 코드가 없어 메트릭 등록 중 오류가 발생해도 이를 처리하는 방법이 없습니다.
  2. "page.view.count"라는 카운터 이름이 하드코딩되어 있어 향후 변경이 필요할 경우 코드 수정이 필요합니다.
 package com.coffee.api.common.aop

 import io.micrometer.core.instrument.MeterRegistry
 import org.aspectj.lang.JoinPoint
 import org.aspectj.lang.annotation.Aspect
 import org.aspectj.lang.annotation.Before
+import org.slf4j.LoggerFactory
 import org.springframework.stereotype.Component

 @Aspect
 @Component
 class PageViewAspect(
-    private val meterRegistry: MeterRegistry
+    private val meterRegistry: MeterRegistry,
+    private val counterName: String = "page.view.count"
 ) {
+    private val logger = LoggerFactory.getLogger(javaClass)

     @Before("@annotation(pageViewed)")
     fun countPageView(joinPoint: JoinPoint, pageViewed: PageViewed) {
-        val counterName = "page.view.count"
         val tagName = pageViewed.name

-        meterRegistry
-            .counter(counterName, "page", tagName)
-            .increment()
+        try {
+            meterRegistry
+                .counter(counterName, "page", tagName)
+                .increment()
+        } catch (e: Exception) {
+            logger.error("페이지 뷰 메트릭 증가 중 오류 발생: {}", e.message, e)
+        }
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
package com.coffee.api.common.aop
import io.micrometer.core.instrument.MeterRegistry
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.springframework.stereotype.Component
@Aspect
@Component
class PageViewAspect(
private val meterRegistry: MeterRegistry
) {
@Before("@annotation(pageViewed)")
fun countPageView(joinPoint: JoinPoint, pageViewed: PageViewed) {
val counterName = "page.view.count"
val tagName = pageViewed.name
meterRegistry
.counter(counterName, "page", tagName)
.increment()
}
}
package com.coffee.api.common.aop
import io.micrometer.core.instrument.MeterRegistry
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Aspect
@Component
class PageViewAspect(
private val meterRegistry: MeterRegistry,
private val counterName: String = "page.view.count"
) {
private val logger = LoggerFactory.getLogger(javaClass)
@Before("@annotation(pageViewed)")
fun countPageView(joinPoint: JoinPoint, pageViewed: PageViewed) {
val tagName = pageViewed.name
try {
meterRegistry
.counter(counterName, "page", tagName)
.increment()
} catch (e: Exception) {
logger.error("페이지 뷰 메트릭 증가 중 오류 발생: {}", e.message, e)
}
}
}

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.

모니터링 서버 구축 및 Kafka 기반의 CQRS 적용

2 participants