[2편] Spring Boot + Prometheus + Loki 기본 구축

minpractice_jhj·2025년 8월 19일

Side Projects

목록 보기
3/16
post-thumbnail

들어가며

1편에서는 모니터링을 왜 도입했는지, 그리고 OTEL + Grafana 스택을 띄우고 첫 번째 지표를 확인한 과정을 다뤘습니다.

이번 2편에서는 Spring Boot 애플리케이션에서 실제로 메트릭과 로그를 수집하는 과정을 정리합니다.

제가 선택한 도구들, 설정 과정에서 겪은 시행착오, 그리고 실제 Grafana에서 지표와 로그를 확인하는 모습까지 공유합니다.


1. Micrometer + Prometheus 메트릭 수집

Spring Boot는 Actuator를 통해 모니터링 엔드포인트를 제공합니다.

하지만 단순 health 체크만으로는 성능 개선에 필요한 지표를 확보하기 어렵습니다.

그래서 선택한 조합이 Micrometer + Prometheus.

Micrometer는 Spring Boot와 자연스럽게 통합되고, Prometheus는 Grafana와 연동성이 뛰어나기 때문에 장기적인 확장성도 고려할 수 있었습니다.

설정 (application-local.yml)

management:
  endpoints:
    web:
      exposure:
        include:
          - health
          - info
          - prometheus
  metrics:
    distribution:
      percentiles-histogram:
        http.server.requests: true
      percentiles:
        http.server.requests: 0.5, 0.95, 0.99

이 설정으로 /actuator/prometheus 엔드포인트에서 다음을 확인할 수 있습니다:

  • 요청 시간을 히스토그램 단위로 수집
  • 50%, 95%, 99% 백분위수 지표 제공

단순 평균 응답시간이 아닌 백분위수 기반 지표는 성능 튜닝에서 특히 중요합니다.

예를 들어, 평균 응답시간이 빠르더라도 95% 구간에서 느리면 실사용자 경험은 크게 달라집니다.

  • /actuator/prometheushttp_server_requests_seconds_bucket 확인 → Spring Boot가 Prometheus 포맷으로 지표를 내보내고 있음을 검증

  • Grafana Explore → histogram_quantile(0.95, rate(http_server_requests_seconds_bucket[5m])) 조회 결과 → 95% 구간 응답시간을 시각화, 실제 병목 구간 파악에 활용

2. P6Spy + Loki 로그 수집

메트릭만으로는 병목의 원인을 특정하기 어렵습니다.

특히 DB 쿼리 실행 시간은 성능 최적화의 핵심 지표 중 하나입니다.

처음엔 단순 로그를 Promtail로 긁어왔는데, SQL 실행 시간은 보이지 않아서 답답했습니다.

그래서 P6Spy를 도입했습니다.

설정

spy.properties

modulelist=com.p6spy.engine.logging.P6LogFactory
logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat
appender=com.p6spy.engine.spy.appender.Slf4JLogger
logLevel=info

logback-spring.xml

<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
  <http>
    <url>http://localhost:3100/loki/api/v1/push</url>
  </http>
  <format>
    <json>
      <field name="timestamp" pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}" />
      <field name="level" pattern="%level" />
      <field name="message" pattern="%msg" />
      <field name="traceId" pattern="%X{traceId}" />
    </json>
  </format>
</appender>

이 설정으로 SQL 실행 로그가 JSON 형태로 Loki에 저장됩니다.

  • Grafana Explore → Loki → job="pinup-service" 로그 조회 → SQL 로그가 JSON 형태로 쌓이는지 확인

3. docker-compose (최소 버전)

이번 글에서는 Prometheus + Loki + Promtail + Grafana 네 가지 서비스만 다룹니다.

이 네 개만 있어도 “메트릭 + 로그”라는 기본기를 완성할 수 있습니다.

services:
  prometheus:
    image: prom/prometheus
    user: root
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro

  loki:
    image: grafana/loki:2.9.2
    ports:
      - "3100:3100"

  promtail:
    image: grafana/promtail:2.9.2
    volumes:
      - ./logs:/app/logs
      - ./promtail-config.yaml:/etc/promtail/config.yaml
    command: -config.file=/etc/promtail/config.yaml

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:![](https://velog.velcdn.com/images/minpractice_jhj/post/d3d9b717-f161-48fa-9970-bb70323c982d/image.png)

      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin

Postgres, Tempo, OTEL Collector는 후속편에서 다룹니다.


마무리

이번 편에서 배운 점:

  • Micrometer + Prometheus → 백분위수 기반 지표 확보
  • P6Spy + Loki → SQL 실행 로그를 JSON 형태로 수집, 병목 분석 기반 마련
  • docker-compose 최소 구성 → 메트릭 + 로그 두 축 확보
profile
운동처럼 개발도 작은 실천이 성장의 힘이 된다고 믿는 개발자 minpractice_jhj 기록

0개의 댓글