
1편에서는 모니터링을 왜 도입했는지, 그리고 OTEL + Grafana 스택을 띄우고 첫 번째 지표를 확인한 과정을 다뤘습니다.
이번 2편에서는 Spring Boot 애플리케이션에서 실제로 메트릭과 로그를 수집하는 과정을 정리합니다.
제가 선택한 도구들, 설정 과정에서 겪은 시행착오, 그리고 실제 Grafana에서 지표와 로그를 확인하는 모습까지 공유합니다.
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 엔드포인트에서 다음을 확인할 수 있습니다:
단순 평균 응답시간이 아닌 백분위수 기반 지표는 성능 튜닝에서 특히 중요합니다.
예를 들어, 평균 응답시간이 빠르더라도 95% 구간에서 느리면 실사용자 경험은 크게 달라집니다.

/actuator/prometheus → http_server_requests_seconds_bucket 확인 → Spring Boot가 Prometheus 포맷으로 지표를 내보내고 있음을 검증
histogram_quantile(0.95, rate(http_server_requests_seconds_bucket[5m])) 조회 결과 → 95% 구간 응답시간을 시각화, 실제 병목 구간 파악에 활용메트릭만으로는 병목의 원인을 특정하기 어렵습니다.
특히 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에 저장됩니다.

job="pinup-service" 로그 조회 → SQL 로그가 JSON 형태로 쌓이는지 확인이번 글에서는 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:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
Postgres, Tempo, OTEL Collector는 후속편에서 다룹니다.
이번 편에서 배운 점: