포폴/일정관리앱

Spring 서비스의 운영 모니터링 환경 구축기1: Prometheus, Grafana, Loki, Kafka/Redis Exporter

slown 2025. 6. 17. 08:24

목차

1.도입: 왜 도입을 했는가?

2.아키텍처 개요

3.Prometheus로 메트릭 수집

4.Loki + Promtail로그 수집

5. Grafana로 통합 대시보드 구성

6.느낀점

 

1.도입: 왜 도입을 했는가?

일정관리 프로젝트 개발 초기에는 Spring Boot의 MDC(Mapped Diagnostic Context)를 활용해서 requestId, username 등의 식별자를 로그에 포함시키고, 콘솔(logback)을 통해 디버깅을 진행했다.

MDC.put("requestId", UUID.randomUUID().toString());
MDC.put("username", authentication.getName());
<!-- logback-spring.xml -->
<pattern>
  {
    "timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}",
    "level": "%level",
    "logger": "%logger",
    "message": "%message",
    "requestId": "%X{requestId}",
    "email": "%X{email}"
  }
</pattern>

 

이 방식은 로컬 개발 환경에서는 효과적이었다. IDE 콘솔에서 실시간으로 로그를 확인을 할 수 있었고, requestId 기반으로 로직의 흐름을 추적할 수 있었기 때문이다. 

 

하지만 이 방식은 배포 이후, 아래와 같은 문제에 직면을 하게 되었다. 

 

  • 로그 접근 불편
    • 서버에서는 콘솔이 아닌 로그 파일(/var/log/...)로 남기 때문에, 일일이 ssh에 접속을 해서 tail,grep를  해야된다는 점
  • 실시간 추적 불가
    • 여러 요청이 동시에 처리가 되면 어떤 요청이 어떤 로그인지가 혼동이 되기 시작함
  • 분산 로그 수집 어려움
    • Kafka,Redis 등의 로그는 백엔드 로그와 분리되어 있어서 전체 흐름 파악이 어려움
  • 시각화가 없음
    • 배포를 하게 되면 서버의 메모리 및 JVM Memory, API 응답속도, GC 동작 등을 숫자나 그래프로 볼 수가 없음.

이러한 이유로 인해서 실시간 모니터링 시스템을 도입을  하기로 했습니다. 

운영 환경에서는 로그를 단순히 보는 것만으로는 부족하다는 판단하에, 다음 요소들을 고려하여 관측성(observability) 시스템을 도입하게 됐다.

  • Loki + Promtail: 구조화된 JSON 로그를 수집하여 요청 단위 추적 가능
  • Prometheus: 메트릭(JVM, Redis, Kafka 상태) 수집
  • Grafana: 대시보드로 시각화 및 빠른 문제 진단

2.아키텍처 개요

이번에 구축을 할 모니터링 아키텍처는 아래의 사진과 같습니다.

 

위의 아키텍처를 설명을 하면 다음과 같습니다. 

  • 로그 기반 모니터링 시스템
    • Spring Boot, Redis, Kafka 로그를 각각 Promtail이 수집
    • Loki에 전송된 로그를 Grafana에서 시각화
    • MDC 기반 JSON 로그 포맷으로 requestId, email 등 필터링 가능
  • 메트릭 기반 모니터링 시스템
    • Spring Boot는 /actuator/prometheus 메트릭을 노출
    • Redis/Kafka는 Exporter를 통해 상태 정보 전달
    • Prometheus가 메트릭을 주기적으로 수집하고 Grafana에서 시각화

 

3.Prometheus로 메트릭 수집

Prometheus는 시계열 DB 기반 매트릭 수집 시스템이다. 이번 프로젝트에서는 다음과 같이 지표들을 수집을 했다.

 

수집대상

  • Spring Boot : JVM Memory, Heap 사용량, GC시간, HTTP 요청수/속도 등
  • Redis: Key수, 메모리 사용량, 연결 수, latency 등
  • Kafka: Borker 상태, Topic lag,파티션 수, consumer offset등

구성 방식

  • docker-compose.dev.yml 파일 내에 Promethus 서비스 정의
  • 각 서비스에 exporter를 설치를 하고 targets 설정을 통해서 Prometheus가 주기적으로 메트릭을 수집
  • 메트릭은 기본적으로 15초 간격(scrape_interval)으로 수집
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'spring-boot'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['api.schedulemanagement.site:8082']

  - job_name: 'kafka'
    static_configs:
      - targets: ['api.schedulemanagement.site:9308']

  - job_name: 'redis'
    static_configs:
      - targets: ['api.schedulemanagement.site:9121']

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['api.schedulemanagement.site:9100']

 

4.Loki + Promtail로그 수집

로그 수집에는 Grafana의 Loki와 Promtail을 사용했습니다. Promtail은 각 컨테이너의 로그 디렉토리를 tail하여 Loki로 전송을 하고, Loki는 수신된 로그를 Grafana를 통해서 시각화 가능하게 해줍니다.

 

구성 방식

  • 로그 파일은 컨테이너에서 /var/log/schedule-backend/app.log 로 출력이 되도록 logback을 설정
  • Promtail은 해당 경로의 로그를 감시(tailing)하여 Loki로 전송
  • JSON 포맷 로그를 사용해 필터링 및 검색 용이
# log-back예시
<pattern>
    <pattern>
        {
        	"level": "%level",
            "thread": "%thread",
            "logger": "%logger",
            "message": "%message",
            "requestId": "%X{requestId}"
        }
    </pattern>
</pattern>

 

장점

  • requestId 기준으로 백엔드 로그를 추적 가능( MDC 활용)
  • Kafka,Redis,Spring 로그를 한 화면에서 통합 조회 가능
  • 에러, WARN 로그를 수준별로 필터링하거나 특정 사용자 기반 검색 가능 

5. Grafana로 통합 대시보드 구성

Grafana는 Loki와 Prometheus 데이터를 시각화해주는 대시보드 툴입니다.

 

구성

  • 매트릭 대시보드: CPU사용률, JVM Heap, Kafka Broker 상태, Redis Memory Api 요청 속도 등

6.느낀점

단순한 콘솔 로그 기반 디버깅에서 벗어나, 실시간 메트릭과 로그를 통합적으로 모니터링함으로써 다음과 같은 이점을 느낄 수 있었습니다.

  • 운영 장애 대응 속도 향상
    • 이전에는 오류 원인 파악에 grep,tail 등 수작업이 필요했겠지만, 지금은 Grafana 대시보드에서 즉시 확인 가능해졌다.
  • 서비스 병목 지점 파악
    • Prometheus 기반 메트릭 덕분에 API 응답속도와 GC 시간이 튀는 구간을 빠르게 확인할 수 있었다. 
  • Kafak/Redis와의 연결성 확보
    • 단순한 backend 관찰을 넘어서, 이벤트 흐름 전체(Kafka->consumer->DLQ재처리)를 추적 가능해졌다.
  • 결론
    • 실시간 모니터링 시스템을 직접 구축하면서 운영 환경에서의 관측성의 중요성을 체감했습니다. 
    • 단순한 개발자 수준을 넘어, 서비스를 운영하는 개발자로서의 경험을 쌓을 수 있었고, 추후 무중단 배포,슬로우 쿼리 분석까지 확장 가능한 기반을 마련했다.