Skip to content

[#143] feat: otel 의존성 추가 및 yml 파일 변경#153

Open
LeeJoEun-01 wants to merge 2 commits intodevelopfrom
feat/#143
Open

[#143] feat: otel 의존성 추가 및 yml 파일 변경#153
LeeJoEun-01 wants to merge 2 commits intodevelopfrom
feat/#143

Conversation

@LeeJoEun-01
Copy link
Contributor

📌 Summary

  • otel 의존성 추가 및 yml 파일 변경

✍️ Description

💡 PR Point

📚 Reference

🔥 Test

@LeeJoEun-01 LeeJoEun-01 self-assigned this Nov 26, 2025
@LeeJoEun-01 LeeJoEun-01 added the 🎒 feat 새로운 기능 추가 label Nov 26, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 2025

📝 Walkthrough

Summary by CodeRabbit

  • 새로운 기능
    • 메트릭 수집 및 OTLP 기반 내보내기 기능이 추가되었습니다.
    • 애플리케이션 정보 및 메트릭 엔드포인트가 공개되었습니다.
    • 메트릭에 애플리케이션 및 네임스페이스 태그가 적용되었습니다.

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

개요

OpenTelemetry 기반 메트릭 수집 기능을 활성화하기 위해 의존성을 추가하고 관리 엔드포인트 및 OTLP 메트릭 내보내기를 구성했습니다. 기존 로직 변경 없이 설정 및 라이브러리 선언만 추가되었습니다.

변경 사항

집단 / 파일 변경 요약
OpenTelemetry 의존성 추가
build.gradle
io.micrometer:micrometer-tracing-bridge-otel, io.opentelemetry:opentelemetry-exporter-otlp, io.micrometer:micrometer-registry-otlp 의존성 추가
메트릭 내보내기 설정
src/main/resources/application.yml
OTLP 메트릭 내보내기 URL 및 step 설정 추가; 관리 엔드포인트에 info, metrics 추가; 메트릭 태그(application, namespace) 정의; simple 및 prometheus 메트릭 내보내기 비활성화

코드 리뷰 예상 소요 시간

🎯 1 (간단함) | ⏱️ ~5분

  • 변경 사항이 구성 파일 및 의존성 선언에 국한되어 있으며, 복잡한 로직이나 제어 흐름 변경이 없음
  • 각 설정 항목의 목적과 OTLP 구성 파라미터가 올바르게 설정되었는지 확인 필요

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 사항과 관련이 있으며, OpenTelemetry 의존성 추가와 yml 파일 변경이라는 주요 변경 사항을 명확히 요약하고 있습니다.
Description check ✅ Passed PR 설명이 변경 사항과 관련이 있으며, OpenTelemetry 의존성 추가 및 yml 파일 변경에 대해 언급하고 있고 연결된 이슈 #143을 참고하고 있습니다.
Linked Issues check ✅ Passed PR은 이슈 #143의 'OpenTelemetry 연결' 목표를 충족하며, build.gradle에 필요한 의존성을 추가하고 application.yml에 OTLP 메트릭 내보내기 설정을 구성했습니다.
Out of Scope Changes check ✅ Passed 모든 변경 사항이 OpenTelemetry 연결 설정 범위 내에 있으며, build.gradle 의존성 추가와 application.yml 설정 변경만 포함되어 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#143

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
Contributor

@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)
build.gradle (1)

33-34: OpenTelemetry 의존성에 명시적 버전 지정 필요

추가된 세 가지 OTEL 의존성이 명시적 버전 번호 없이 선언되었습니다. 이는 전이 의존성 버전 충돌을 초래할 수 있으며, Spring Boot 3.5.7 및 기존 micrometer 스택과의 호환성 확인이 필요합니다.

권장사항:

  • Spring Boot의 BOM(Bill of Materials) 버전과 정렬된 명시적 버전 지정
  • 예: io.micrometer:micrometer-tracing-bridge-otel:1.x.xio.opentelemetry:opentelemetry-exporter-otlp:1.x.x

Also applies to: 52-52

src/main/resources/application.yml (1)

49-52: metrics.tags 설정이 부분적으로만 환경 변수화됨

management.metrics.tags 설정에서 application 태그는 정적 값을 사용하지만, 네임스페이스는 환경 변수를 사용하고 있습니다. 일관성 유지를 위해 다른 태그들도 환경 변수로 제공되는지 확인하거나, 둘 다 정적으로 설정할 것을 권장합니다.

현재 설정에서 K8S_NAMESPACE 환경 변수가 정의되지 않으면 unknown으로 설정되는데, OTEL 수집기 URL이 하드코딩되어 있으므로 두 설정 간의 불일치가 발생할 수 있습니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1c046a and 5a98bfd.

📒 Files selected for processing (2)
  • build.gradle (2 hunks)
  • src/main/resources/application.yml (1 hunks)
🔇 Additional comments (2)
src/main/resources/application.yml (2)

54-61: Simple 및 Prometheus 메트릭 내보내기 비활성화 확인

Simple 및 Prometheus 메트릭 내보내기가 명시적으로 비활성화되었습니다. 이는 OTLP로의 단일 메트릭 내보내기 경로를 보장하는 좋은 설정입니다.


42-42: Actuator 엔드포인트 노출 변경 확인

management.endpoints.web.exposure.includehealth에서 health,info,metrics로 확장되었습니다. 메트릭 수집을 위한 /actuator/metrics 엔드포인트를 노출하는 것이 목적으로 보이며, 이는 적절합니다.

보안 검토: 프로덕션 환경에서 이러한 엔드포인트 노출이 의도된 것인지, 필요한 인증/권한 설정이 있는지 확인하세요.

Comment on lines +43 to +47
otlp:
metrics:
export:
url: http://ipiece-otel-collector.monitoring:4318/v1/metrics
step: 5s
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Script executed:

#!/bin/bash

# First, find and read the application.yml file
find . -name "application.yml" -type f | head -20

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

./src/main/resources/application.yml
./src/test/resources/application.yml

</shell_result>


Script executed:

#!/bin/bash

# Read the main application.yml to see the exact configuration
cat -n ./src/main/resources/application.yml | head -70

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

     1	spring:
     2	  application:
     3	    name: IPiece
     4	  profiles:
     5	    active: local
     6	  servlet:
     7	    multipart:
     8	      max-file-size: 50MB
     9	      max-request-size: 50MB
    10	
    11	
    12	  datasource:
    13	    url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}
    14	    username: ${DB_USER}
    15	    password: ${DB_PASS}
    16	
    17	  data:
    18	    redis:
    19	      host: ${REDIS_HOST}
    20	      port: ${REDIS_PORT}
    21	
    22	  jpa:
    23	    hibernate:
    24	      ddl-auto: update
    25	    properties:
    26	      hibernate:
    27	        format_sql: true
    28	        highlight_sql: true  # (Spring Boot 3.1+) SQL 색상 강조
    29	    show-sql: true        # SQL 쿼리 출력
    30	
    31	
    32	server:
    33	  error:
    34	    include-message: always
    35	    include-stacktrace: never
    36	    include-binding-errors: never
    37	
    38	management:
    39	  endpoints:
    40	    web:
    41	      exposure:
    42	        include: health,info,metrics
    43	  otlp:
    44	    metrics:
    45	      export:
    46	        url: http://ipiece-otel-collector.monitoring:4318/v1/metrics
    47	        step: 5s
    48	
    49	  metrics:
    50	    tags:
    51	      application: ${spring.application.name}
    52	      namespace: ${K8S_NAMESPACE:unknown}
    53	
    54	  simple:
    55	    metrics:
    56	      export:
    57	        enabled: false
    58	  prometheus:
    59	    metrics:
    60	      export:
    61	        enabled: false
    62	
    63	jwt:
    64	  secret: ${JWT_SECRET}
    65	  expiration-ms: 241920000          # AccessToken 28일 -> 개발 완료 후 조정 필요
    66	  refresh-expiration-ms: 604800000 # RefreshToken 7일
    67	
    68	krwt:
    69	  contract:
    70	    address: ${KRWT_CONTRACT_ADDRESS}

</shell_result>


Script executed:

#!/bin/bash

# Check for Spring profile-specific configuration files
find ./src/main/resources -name "application*.yml" -o -name "application*.yaml" | sort

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

./src/main/resources/application.yml

</shell_result>


Script executed:

#!/bin/bash

# Search for OTEL or OTLP references in the codebase
rg -i "otel|otlp" --type yaml --type md --type java --type kotlin -C 3 | head -100

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

src/main/resources/application.yml-    web:
src/main/resources/application.yml-      exposure:
src/main/resources/application.yml-        include: health,info,metrics
src/main/resources/application.yml:  otlp:
src/main/resources/application.yml-    metrics:
src/main/resources/application.yml-      export:
src/main/resources/application.yml:        url: http://ipiece-otel-collector.monitoring:4318/v1/metrics
src/main/resources/application.yml-        step: 5s
src/main/resources/application.yml-
src/main/resources/application.yml-  metrics:

</shell_result>


Script executed:

#!/bin/bash

# Check for README and documentation
find . -maxdepth 2 -type f \( -name "README*" -o -name "*.md" \) | head -20

echo "---"

# Look for docker-compose or k8s files that might reference the monitoring namespace
find . -type f \( -name "docker-compose*" -o -name "*.yaml" -o -name "*.yml" \) | grep -v ".git" | grep -E "(docker|k8s|kube|deployment)" | head -20

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

./README.md
---

</shell_result>


Script executed:

#!/bin/bash

# Read README.md to understand deployment context
cat ./README.md

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

# IPiece

</shell_result>


Script executed:

#!/bin/bash

# Search for Docker, K8s, and build files
find . -type f \( -name "Dockerfile*" -o -name "docker-compose*" -o -name "pom.xml" -o -name "build.gradle*" -o -name "*.yaml" -o -name "*.yml" \) | grep -v ".git" | grep -v "target/" | grep -v "node_modules/" | head -40

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

./Dockerfile
./src/main/resources/application.yml
./src/test/resources/application.yml
./build.gradle

</shell_result>


Script executed:

#!/bin/bash

# Read Dockerfile
echo "=== DOCKERFILE ===" 
cat ./Dockerfile

echo ""
echo "=== BUILD.GRADLE (OTEL-related dependencies) ===" 
rg -i "otel|micrometer|observ" ./build.gradle -A 2 -B 2

Repository: Woori-FISA-Go/IPiece-server


<shell_result>
Repository: Woori-FISA-Go/IPiece-server
Exit code: 0

stdout:

=== DOCKERFILE ===
# ===========================
# Stage 1: Build Stage
# ===========================
FROM gradle:8.5-jdk17-alpine AS builder

WORKDIR /app

# Gradle 캐시 레이어 (의존성만 먼저)
COPY build.gradle settings.gradle ./
COPY gradle ./gradle
RUN gradle dependencies --no-daemon || true

# 소스 코드 복사 및 빌드
COPY src ./src
RUN gradle clean build -x test --no-daemon --stacktrace

# JAR 파일 확인
RUN ls -la /app/build/libs/ && \
    test -f /app/build/libs/IPiece-0.0.1-SNAPSHOT.jar

# ===========================
# Stage 2: Runtime Stage (보안 강화)
# ===========================
FROM eclipse-temurin:17-jre-alpine

# 라벨 추가 (메타데이터)
LABEL maintainer="Woori-FISA-Go Team" \
      version="1.0" \
      description="IPiece Backend Server"

WORKDIR /app

# 보안: non-root 사용자 생성 및 디렉토리 권한 설정
RUN addgroup -S spring && \
    adduser -S spring -G spring && \
    chown -R spring:spring /app

# 필요한 패키지만 설치 (보안 업데이트 포함)
RUN apk update && \
    apk upgrade && \
    apk add --no-cache wget && \
    rm -rf /var/cache/apk/*

# JAR 파일 복사 (non-root 소유)
COPY --from=builder --chown=spring:spring /app/build/libs/*.jar app.jar

# 사용자 전환 (non-root로 실행)
USER spring:spring

# Health Check 설정
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1

# 환경변수 (기본값)
ENV SPRING_PROFILES_ACTIVE=prod \
    JAVA_OPTS="-XX:MaxRAMPercentage=75.0 \
               -XX:+UseContainerSupport \
               -Djava.security.egd=file:/dev/./urandom \
               -Dserver.port=8080" \
    TZ=Asia/Seoul

# 포트 노출
EXPOSE 8080

# 실행
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
=== BUILD.GRADLE (OTEL-related dependencies) ===
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-actuator'
	implementation 'io.micrometer:micrometer-tracing-bridge-otel'
	implementation 'io.opentelemetry:opentelemetry-exporter-otlp'
	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6'
--
    implementation 'org.web3j:core:4.10.0'
    implementation 'com.squareup.okhttp3:okhttp:4.12.0'
	runtimeOnly 'io.micrometer:micrometer-registry-otlp'

}

</shell_result>


OTLP 수집기 URL이 환경 설정으로 외부화되지 않음

OTLP 메트릭 수집기 URL이 http://ipiece-otel-collector.monitoring:4318/v1/metrics로 하드코딩되어 있습니다(line 46). 이는 다음과 같은 문제를 야기합니다:

  1. 데이터베이스(DB_HOST, DB_PORT, DB_NAME), Redis(REDIS_HOST, REDIS_PORT), JWT 등 다른 설정들은 모두 환경 변수로 외부화되어 있으나 OTLP URL만 하드코딩됨
  2. Kubernetes 네임스페이스 monitoring이 고정되어 있어 다른 환경에서 배포 불가
  3. Dockerfile의 SPRING_PROFILES_ACTIVE=prod 설정에도 불구하고 profile별 application-*.yml 파일이 없어 환경 간 설정 분리 불가
  4. 로컬 개발 환경에서 별도의 OTEL 수집기가 없을 경우 실행 불가

권장사항: OTEL 수집기 URL을 환경 변수로 외부화하세요. Spring Boot/Micrometer는 OTEL_EXPORTER_OTLP_ENDPOINT 환경 변수를 기본적으로 지원합니다.

management:
  otlp:
    metrics:
      export:
        url: ${OTEL_EXPORTER_OTLP_ENDPOINT:http://localhost:4318/v1/metrics}
        step: 5s
🤖 Prompt for AI Agents
In src/main/resources/application.yml around lines 43 to 47, the OTLP metrics
exporter URL is hardcoded to
http://ipiece-otel-collector.monitoring:4318/v1/metrics which prevents
environment-specific configuration and breaks non-cluster/local runs; change it
to read from an environment variable (e.g. OTEL_EXPORTER_OTLP_ENDPOINT) with a
sensible default, update the YAML to use property substitution for the URL, and
ensure documentation/README and Docker/K8s manifests reference and pass this env
var (or define profile-specific application-*.yml files) so each deployment can
override the collector endpoint.

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

Labels

🎒 feat 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenTelemetry 활용해서 메트릭 및 로그 수집

1 participant