Skip to content

chore: 모니터링 환경 구축#476

Merged
jeongyeon0208 merged 5 commits intodevfrom
chore/475-monitoring
Jul 7, 2025
Merged

chore: 모니터링 환경 구축#476
jeongyeon0208 merged 5 commits intodevfrom
chore/475-monitoring

Conversation

@jeongyeon0208
Copy link
Member

@jeongyeon0208 jeongyeon0208 commented Jul 6, 2025

🌱 관련 이슈

close #475


📌 작업 내용 및 특이사항

모니터링 환경 구축 (Prometheus + Grafana + Loki)

  • Spring Boot 애플리케이션의 로그 및 메트릭을 수집/시각화하기 위한 모니터링 환경을 Docker 기반으로 구축
  • 요청/응답 로그는 Loki를 통해 수집하고, 메트릭은 Prometheus를 통해 수집하여 Grafana에서 통합적으로 확인

📁 구성 파일 설명

1. docker-compose-monitoring.yml

  • Prometheus, Grafana, Loki를 Docker로 실행
  • prometheus: /actuator/prometheus에서 메트릭 수집
  • grafana: Loki 및 Prometheus 시각화
  • loki: 구조화된 로그 수집
  • 공통 네트워크 drinkig_monitoring_network로 Spring 컨테이너와 연결
    • docker network create drinkig_monitoring_network 명령어를 통해 미리 네트워크 생성 후 실행 필요

2. prometheus.yml

  • scrape_interval: 메트릭 수집 주기 (15초)
  • 컨테이너 또는 호스트 주소를 지정해 메트릭 수집
  • 로컬에서 인텔리제이를 이용해 스프링을 실행하면 host.docker.internal:8080 타겟 사용

3. loki-config.yml

  • 파일시스템 기반 로그 저장
  • 하루 단위 인덱스
  • 7일 이상 된 로그가 새로 들어오면 수집 거부

4. logback-spring.xml

  • 콘솔과 Loki 모두로 로그 전송
  • traceId를 통한 요청 추적 가능
  • AsyncAppender 설정으로 성능 저하 방지

HTTP 요청/응답 로깅 필터 구현 및 traceId 기반 통합 로깅 적용

  • HTTP 요청과 응답의 상세 내용을 JSON 포맷으로 로그에 기록하는 HttpLoggingFilter 구현
  • 각 요청에 대해 고유한 traceId 생성 및 MDC에 저장하여 로그 추적 용이성 향상
  • 요청 본문을 캐싱하는 RequestWrapper와 응답 본문을 캐싱하는 ResponseWrapper 적용
  • 로그 기록 시 멀티파트 요청, actuator 엔드포인트, 비동기 디스패치 등 예외 상황 처리
  • 요청/응답 로그를 HttpRequestLogInfo, HttpResponseLogInfo DTO로 관리하며, 바디 크기 제한(최대 5KB) 적용
  • Loki, Grafana 등 모니터링 도구와 연동 가능하도록 JSON 형태 로그 포맷과 MDC 활용
  • traceId를 포함해 여러 로그가 쉽게 연관되어 문제 디버깅 및 분석 지원

1. HttpLoggingFilter (로깅 필터)

- OncePerRequestFilter 상속하여 커스텀 필터 구현 
- 요청당 한 번만 실행되도록 shouldNotFilterAsyncDispatch() 오버라이드하여 비동기 재실행 방지
- doFilterInternal()에서 다음 처리:
 - 요청 URI가 /actuator/로 시작하면 필터 동작 건너뜀 (모니터링 엔드포인트 제외)
 - 비동기 디스패치 및 멀티파트 요청도 필터 로깅 대상에서 제외
 - 그 외 요청에 대해 RequestWrapper와 ResponseWrapper를 사용하여 본문 캐싱 후 로깅 수행
 - MDC에 UUID 기반 traceId 생성 후 할당, 필터 종료 시 MDC 정리하여 메모리 누수 방지

2. RequestWrapper (요청 본문 캐싱)

- HttpServletRequestWrapper 상속
- 요청의 InputStream을 바이트 배열로 미리 복사해 둠으로써, 여러 번 읽을 수 있도록 지원
- getInputStream() 메서드 재정의하여 복사된 바이트 배열로부터 스트림 반환
- 본문을 여러 번 읽는 로깅 시나리오에서 InputStream 소모 문제 해결

3. ResponseWrapper (응답 본문 캐싱)

- ContentCachingResponseWrapper를 상속하여 응답 내용을 캐싱
- 필터 종료 시 캐싱된 응답 바이트를 실제 응답 스트림에 다시 복사하여 클라이언트에 전달
- 응답 로그 기록 시 바디를 안전하게 읽을 수 있도록 지원

4. HttpRequestLogInfo & HttpResponseLogInfo (로그 DTO)

- 요청 및 응답 로그 정보를 객체로 추상화하여 JSON 직렬화 가능
- 요청 로그에는 traceId, HTTP 메서드, URI, 쿼리, AWS X-Amzn-Trace-Id, User-Agent 정보 포함
- 응답 로그에는 traceId, HTTP 상태 코드, 응답 바디(최대 5KB) 포함
- 응답 바디는 Content-Type 기준으로 텍스트, JSON 등 읽을 수 있는 타입만 출력하며, 바이너리는 “BINARY”로 표기
- JSON 포맷으로 로그를 찍어 Loki 같은 중앙 집중식 로그 수집시스템에 적합하게 설계

  • Grafana에서 Loki 연결 후 로그 확인
image
  • 인텔리제이 내 콘솔 로그 확인
image

📝 참고사항

📚 기타

@jeongyeon0208 jeongyeon0208 self-assigned this Jul 6, 2025
Copy link
Member

@woogieon8on woogieon8on left a comment

Choose a reason for hiding this comment

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

LGTMMMMMMM

@jeongyeon0208 jeongyeon0208 merged commit a32679d into dev Jul 7, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🔧 모니터링 환경 구축

2 participants