본문 바로가기
프로젝트

Prometheus + Grafana 모니터링 Spring Boot에 추가하기

by jucheol 2025. 11. 15.

Spring Boot 애플리케이션을 운영하다 보면, API 응답 속도 저하나 DB 커넥션 풀 부족, CPU·메모리 spike 등 다양한 장애 신호들이 발생할 수 있다.
이런 문제는 로그만으로는 절대 정확히 보이지 않는다.
그래서 이번 프로젝트에 Prometheus + Grafana 기반 모니터링 시스템을 직접 구축했다.


1. 전체 구조 

[ Spring ↔ Prometheus ↔ Grafana 데이터 흐름 ]

 
사용자가 API 호출
        ↓
Spring Boot
- 요청 처리 시간 기록
- HTTP metrics 생성
- JVM/DB/Redis 상태 기록
- 메트릭을 /actuator/prometheus 에 노출
        ↓
Prometheus
- 5초마다 Spring Boot에서 메트릭을 pull
- 시계열 DB에 저장
        ↓
Grafana
- PromQL 쿼리로 Prometheus 데이터 조회
- Latency, Error Rate, Heap 등 시각화
        ↓
개발자·운영자
- 성능 저하 원인 분석
- 병목 지점 파악

✔ Spring Boot 역할

  • /actuator/prometheus 엔드포인트에서 모든 메트릭을 Prometheus 스크랩 포맷으로 노출
  • HTTP 요청, JVM, DB, Redis, 로깅 등 다양한 메트릭 자동 수집
  • Micrometer가 실제 메트릭 생산 담당

✔ Prometheus 역할

  • Spring Boot의 /actuator/prometheus 엔드포인트를 주기적으로 pull
  • 가져온 메트릭을 시계열(time-series) DB로 저장
  • Grafana가 사용할 수 있도록 Prometheus Query API 제공

✔ Grafana 역할

  • Prometheus에서 PromQL을 이용해 값을 조회
  • 그래프/차트/대시보드로 시각화
  • P90 Latency, Error Rate, RPS 등 모니터링 패널 생성 가능

2. Spring Boot 설정

1. build.gradle

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'

2. Actuator + Metric 설정 - application.yml 

1. Actuator 엔드포인트 노출 설정

 
management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus,metrics

✔ 의미

HTTP로 접근 가능한 Actuator Endpoint 목록을 지정하는 설정이다.

  • health – 애플리케이션 상태(UP/DOWN)
  • info – 애플리케이션 빌드 정보
  • metrics – Micrometer 기본 메트릭(CPU, memory, HTTP 요청 등)
  • prometheus – Prometheus가 데이터를 긁어가는(scrape) 전용 엔드포인트

이 설정으로 브라우저에서 아래 URL을 호출할 수 있게 된다:

  • http://localhost:8081/actuator/health
  • http://localhost:8081/actuator/metrics
  • http://localhost:8081/actuator/prometheus

Prometheus 환경에서는 prometheus 엔드포인트 노출이 필수다.

 

 

2. Health 상세 정보 표시

endpoint:
  health:
    show-details: always

✔ 의미

기본적으로 /actuator/health 는 “UP/DOWN”만 반환한다.
이 설정을 통해 DB, Redis, DiskSpace 등 세부 상태까지 모두 표시한다.

운영 환경에서는 보안상 “when-authorized”로 두기도 한다.

 

 

3. Metrics 기본 태그 추가

endpoint:
  health:
    show-details: always
 

✔ 의미

모든 메트릭에 공통 태그 application=music-place 를 자동으로 추가한다.

Prometheus/Grafana에서 여러 서비스가 있을 때
서비스 별 filtering or grouping 을 쉽게 하기 위해 사용하는 설정이다.

 

 

4. HTTP 요청 메트릭의 퍼센타일 / 히스토그램 설정

distribution:
  percentiles-histogram:
    http.server.requests: true     # histogram 활성화
  percentiles:
    http.server.requests: 0.5, 0.9, 0.95

✔ 의미

Micrometer의 HTTP 요청 메트릭(http.server.requests)을 다음과 같이 확장한다.

✔ 히스토그램 활성화

  • 요청 처리 시간 구간별(bucket)로 데이터를 저장
  • Prometheus의 p50, p90, p95, p99 같은 지연 시간 분석에 필수
  • latency 기반의 성능 분석에 매우 유용

✔ 퍼센타일 설정

  • 0.5 (50%), 0.9 (90%), 0.95 (95%) 요청이
    각각 어느 정도의 응답 시간을 보였는지 계산하도록 Micrometer에 지시한다.

👉 실시간 성능 모니터링(Grafana Dashboard)에서 가장 많이 사용하는 값들이다.

 

 

5. HTTP Observations 활성화

observations:
  http:
    server:
      requests:
        enabled: true

✔ 의미

Micrometer Observation API 기반으로
HTTP 요청/응답에 대한 trace-like 메타데이터를 수집하는 설정이다.

  • 요청 처리 시간
  • 예외
  • 상태 코드별 통계

등이 더 정교하게 기록된다.

Observability(관찰 가능성) 기능을 확장하는 옵션이다.

 

 

6. Prometheus Exporter 활성화

 
prometheus:
  metrics:
    export:
      enabled: true

✔ 의미

Micrometer가 수집한 모든 메트릭을
Prometheus 형식으로 변환하여 /actuator/prometheus 로 내보내는 기능을 활성화한다.

Prometheus 서버는 이 엔드포인트를 주기적으로 호출(scrape)해 데이터를 가져간다.

 

 

7. Actuator 서버 포트 분리

server:
  port: 8081
 

✔ 의미

Actuator 및 Prometheus 엔드포인트를
일반 API 서버 포트(예: 8080)와 분리하기 위해 별도의 포트에서 실행시키는 설정이다.

운영 환경에서 흔히 사용하는 패턴이다.

  • 8080 → 일반 API
  • 8081 → health, metrics, prometheus 용도

보안/성능 관리 측면에서 효과적이다.


3. Prometheus 설정 - prometheus.yml

global:
  scrape_interval: 15s # 15초마다 메트릭 수집
  evaluation_interval: 15s # alert rule 평가 간격

scrape_configs:
  - job_name: 'musicplace-backend'
    metrics_path: '/actuator/prometheus' # 스프링 부트 지표 경로
    static_configs:
      - targets: ['host.docker.internal:8081'] # Spring Boot 애플리케이션 주소
        labels:
          instance: 'spring-app'

왜 host.docker.internal인가?

Windows 환경에서 Docker 컨테이너가 host OS의 서버에 접근하려면 host.docker.internal을 사용해야 한다.
처음에 localhost:8081을 넣었다가 메트릭이 수집되지 않는 문제가 있었다.


4. Docker Compose 구성 — Prometheus & Grafana 실행

prometheus:
    image: prom/prometheus:latest
    container_name: musicplace_prometheus
    restart: always
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'

  grafana:
    image: grafana/grafana:latest
    container_name: musicplace_grafana
    restart: always
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
      - ./monitoring/grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards
    depends_on:
      - prometheus

volumes:
  grafana_data:

5. 내가 겪었던 문제들 & 해결 과정

Grafana에서 데이터를 가져오지 못해 no data가 발생

문제 1 — Prometheus가 Spring Boot 메트릭을 못 가져옴

원인: localhost:8081 접근 불가 (Docker 환경 특성)
해결: host.docker.internal:8081로 대상 수정
결과: /actuator/prometheus 메트릭 정상 스크랩


문제 2 — Grafana Latency(P90/P95)가 표시되지 않음

원인: histogram 비활성화
해결: percentiles-histogram: http.server.requests: true 설정
결과: http_server_requests_seconds_bucket 메트릭 생성됨


문제 3 — Error Rate(5xx) 그래프에 No Data

원인: 해당 시점에 실제 5xx가 발생하지 않음
해결: 임의로 오류 API를 호출하여 정상 동작 확인
결과: 비율 계산 정상 표시


문제 4 — HikariCP 상태 확인 필요

Prometheus에서 아래 지표를 직접 확인해 DB 병목 가능성을 분석했다.

hikaricp_connections_active
hikaricp_connections_idle
hikaricp_connections_pending

Idle이 0에 가까우면 DB 커넥션 부족 신호다.