본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 8장: Grafana, Jaeger, Prometheus 연동
2026년 2월 22일·인프라·

8장: Grafana, Jaeger, Prometheus 연동

Jaeger로 분산 추적을 시각화하고, Prometheus로 메트릭을 저장/쿼리하며, Grafana로 통합 대시보드를 구성합니다. Docker Compose로 전체 스택을 실습합니다.

12분710자9개 섹션
monitoringobservability
공유
opentelemetry8 / 11
1234567891011
이전7장: Collector 아키텍처와 배포다음9장: AI 서비스 관측 가능성

학습 목표

  • Jaeger를 통한 분산 추적 저장과 검색 방법을 학습합니다
  • Prometheus의 메트릭 저장과 PromQL 쿼리를 이해합니다
  • Grafana Tempo와 Loki의 역할을 파악합니다
  • Grafana 대시보드에서 3대 신호를 통합 시각화합니다
  • Docker Compose로 전체 관측 가능성 스택을 구축합니다

백엔드 아키텍처 개요

OpenTelemetry는 백엔드에 독립적이지만, 실무에서 가장 널리 사용되는 오픈소스 조합은 다음과 같습니다.

신호백엔드역할
트레이스Jaeger 또는 Grafana Tempo분산 추적 저장/검색
메트릭Prometheus시계열 메트릭 저장/쿼리
로그Grafana Loki로그 저장/검색
시각화Grafana통합 대시보드/알림

Jaeger — 분산 추적 백엔드

Jaeger는 Uber에서 개발하여 CNCF에 기증한 분산 추적 백엔드입니다. 트레이스 저장, 검색, 시각화, 서비스 의존성 그래프 기능을 제공합니다.

Jaeger의 주요 기능

  • 트레이스 검색 — 서비스명, 작업명, 태그, 지연 시간으로 트레이스 필터링
  • 트레이스 비교 — 두 트레이스를 나란히 놓고 차이점 분석
  • 서비스 의존성 — 서비스 간 호출 관계를 자동으로 시각화
  • 스팬 분석 — 개별 스팬의 속성, 이벤트, 에러 상세 조회

Collector에서 Jaeger로 연동

collector-jaeger.yaml
yaml
exporters:
  otlp/jaeger:
    endpoint: "jaeger:4317"
    tls:
      insecure: true
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/jaeger]

Jaeger v2부터는 OTLP를 네이티브로 지원하므로, OTel Collector의 OTLP exporter로 직접 전송할 수 있습니다. 별도의 Jaeger 전용 exporter가 필요하지 않습니다.

Grafana Tempo — 차세대 트레이스 백엔드

Grafana Tempo는 Grafana Labs가 개발한 대규모 분산 추적 백엔드입니다. Jaeger와 달리 인덱싱 없이 오브젝트 스토리지(S3, GCS)에 직접 저장하여 운영 비용을 크게 낮춥니다.

tempo-config.yaml
yaml
server:
  http_listen_port: 3200
 
distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: "0.0.0.0:4317"
 
storage:
  trace:
    backend: local
    local:
      path: /var/tempo/traces
    wal:
      path: /var/tempo/wal
 
metrics_generator:
  storage:
    path: /var/tempo/generator/wal
    remote_write:
      - url: http://prometheus:9090/api/v1/write
Tip

Tempo의 metrics_generator 기능은 트레이스 데이터에서 자동으로 RED 메트릭(Rate, Error, Duration)을 생성합니다. 별도의 메트릭 계측 없이도 서비스별 요청 처리량, 에러율, 지연 시간 메트릭을 얻을 수 있어 초기 도입 시 매우 유용합니다.


Prometheus — 메트릭 백엔드

Prometheus는 CNCF 졸업 프로젝트이자 시계열 메트릭 저장소의 사실상 표준입니다. Pull 모델(스크레이핑)을 기본으로 하지만, Remote Write를 통한 Push 모델도 지원합니다.

OTel Collector와 Prometheus 연동

두 가지 연동 방식이 있습니다.

방식 1: Prometheus Exporter (Pull)

Collector가 Prometheus 형식으로 메트릭을 노출하고, Prometheus가 스크레이핑합니다.

collector-prometheus-pull.yaml
yaml
exporters:
  prometheus:
    endpoint: "0.0.0.0:8889"
    namespace: "otel"
 
service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [prometheus]

방식 2: Prometheus Remote Write (Push)

Collector가 Prometheus에 직접 메트릭을 Push합니다.

collector-prometheus-push.yaml
yaml
exporters:
  prometheusremotewrite:
    endpoint: "http://prometheus:9090/api/v1/write"
    resource_to_telemetry_conversion:
      enabled: true
 
service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [prometheusremotewrite]

PromQL 활용 예시

OTel 메트릭을 Prometheus에 저장한 후 PromQL로 쿼리합니다.

핵심 PromQL 쿼리
promql
# 서비스별 초당 요청 처리량 (RPS)
rate(otel_http_server_request_count_total[5m])
 
# p99 응답 지연 시간
histogram_quantile(0.99,
  rate(otel_http_server_request_duration_seconds_bucket[5m])
)
 
# 에러율 (5xx 비율)
sum(rate(otel_http_server_request_count_total{http_response_status_code=~"5.."}[5m]))
/
sum(rate(otel_http_server_request_count_total[5m]))
 
# 서비스별 활성 요청 수
otel_http_server_active_requests

Grafana Loki — 로그 백엔드

Grafana Loki는 "Prometheus for logs"를 표방하는 로그 집계 시스템입니다. 로그 내용을 인덱싱하지 않고 레이블만 인덱싱하여 저장 비용을 낮춥니다.

collector-loki.yaml
yaml
exporters:
  otlp/loki:
    endpoint: "http://loki:3100/otlp"
    tls:
      insecure: true
 
service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/loki]

LogQL 활용 예시

핵심 LogQL 쿼리
logql
# 특정 서비스의 에러 로그 검색
{service_name="order-service"} |= "ERROR"
 
# JSON 파싱 후 필터링
{service_name="payment-service"} | json | error_type = "InsufficientFunds"
 
# 로그에서 trace_id 추출하여 트레이스 연결
{service_name="user-service"} | json | line_format "trace: {{.trace_id}}"
 
# 분당 에러 로그 수 집계
count_over_time({service_name="order-service"} |= "ERROR" [1m])

Grafana 통합 대시보드

Grafana는 세 가지 백엔드를 하나의 대시보드에서 통합 시각화합니다.

데이터 소스 설정

grafana-datasources.yaml
yaml
apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    isDefault: true
    jsonData:
      exemplarTraceIdDestinations:
        - name: trace_id
          datasourceUid: tempo
  
  - name: Tempo
    type: tempo
    url: http://tempo:3200
    uid: tempo
    jsonData:
      tracesToLogs:
        datasourceUid: loki
        filterByTraceID: true
      tracesToMetrics:
        datasourceUid: prometheus
  
  - name: Loki
    type: loki
    url: http://loki:3100
    jsonData:
      derivedFields:
        - datasourceUid: tempo
          matcherRegex: "trace_id=(\\w+)"
          name: TraceID
          url: "$${__value.raw}"

신호 간 연결 흐름

Grafana에서의 3대 신호 연결은 다음과 같이 동작합니다.

  1. 메트릭 → 트레이스: Prometheus 그래프에서 Exemplar 점을 클릭하면 해당 트레이스로 이동
  2. 트레이스 → 로그: Tempo 스팬 상세에서 "Logs for this span" 버튼으로 관련 로그 조회
  3. 로그 → 트레이스: Loki 로그의 trace_id 링크를 클릭하면 트레이스로 이동
Info

이 순환적 연결이 관측 가능성의 핵심입니다. 메트릭으로 이상을 감지하고, 트레이스로 원인을 추적하고, 로그로 상세 맥락을 확인하는 워크플로우가 자연스럽게 연결됩니다.


Docker Compose 전체 스택 실습

전체 관측 가능성 스택을 Docker Compose로 한 번에 구성합니다.

docker-compose.yaml
yaml
services:
  # --- 애플리케이션 ---
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317
      - OTEL_SERVICE_NAME=demo-app
    depends_on:
      - collector
 
  # --- OTel Collector ---
  collector:
    image: otel/opentelemetry-collector-contrib:0.100.0
    volumes:
      - ./config/otel-collector.yaml:/etc/otelcol/config.yaml
    ports:
      - "4317:4317"
      - "4318:4318"
      - "8889:8889"
    depends_on:
      - tempo
      - prometheus
      - loki
 
  # --- 트레이스 백엔드 ---
  tempo:
    image: grafana/tempo:2.4.1
    volumes:
      - ./config/tempo.yaml:/etc/tempo/config.yaml
    command: ["-config.file=/etc/tempo/config.yaml"]
    ports:
      - "3200:3200"
 
  # --- 메트릭 백엔드 ---
  prometheus:
    image: prom/prometheus:v2.51.0
    volumes:
      - ./config/prometheus.yaml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--web.enable-remote-write-receiver"
      - "--enable-feature=exemplar-storage"
 
  # --- 로그 백엔드 ---
  loki:
    image: grafana/loki:2.9.6
    ports:
      - "3100:3100"
    command: ["-config.file=/etc/loki/local-config.yaml"]
 
  # --- 시각화 ---
  grafana:
    image: grafana/grafana:10.4.1
    volumes:
      - ./config/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
    depends_on:
      - tempo
      - prometheus
      - loki

OTel Collector 설정

config/otel-collector.yaml
yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: "0.0.0.0:4317"
      http:
        endpoint: "0.0.0.0:4318"
 
processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
    spike_limit_mib: 128
 
  batch:
    timeout: 1s
    send_batch_size: 1024
 
exporters:
  otlp/tempo:
    endpoint: "tempo:4317"
    tls:
      insecure: true
 
  prometheusremotewrite:
    endpoint: "http://prometheus:9090/api/v1/write"
    resource_to_telemetry_conversion:
      enabled: true
 
  otlp/loki:
    endpoint: "http://loki:3100/otlp"
    tls:
      insecure: true
 
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheusremotewrite]
    logs:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/loki]

실행과 확인

스택 실행
bash
# 전체 스택 시작
docker compose up -d
 
# 상태 확인
docker compose ps
 
# 테스트 요청 전송
curl -X POST http://localhost:8080/orders \
  -H "Content-Type: application/json" \
  -d '{"items": ["item-1"], "total": 25000}'
 
# Grafana 접속: http://localhost:3000
# Jaeger UI 접속 (사용 시): http://localhost:16686

Exemplars 실전 활용

Exemplars가 Prometheus와 Grafana에서 동작하는 전체 흐름을 확인합니다.

Prometheus 설정

config/prometheus.yaml
yaml
global:
  scrape_interval: 15s
 
# Exemplar 저장 활성화 (--enable-feature=exemplar-storage 플래그 필요)

Grafana에서 Exemplar 확인

  1. Grafana에서 Prometheus 데이터 소스의 패널을 생성합니다
  2. PromQL 쿼리에 Histogram 메트릭을 사용합니다
  3. 패널 설정에서 "Exemplars" 토글을 활성화합니다
  4. 그래프 위의 작은 점이 Exemplar이며, 클릭하면 trace_id가 표시됩니다
  5. trace_id 링크를 클릭하면 Tempo로 이동하여 해당 트레이스를 확인합니다

정리

이번 장에서는 OTel Collector에서 수집한 3대 신호를 각 백엔드로 연동하는 방법을 학습했습니다. Jaeger/Tempo로 트레이스를, Prometheus로 메트릭을, Loki로 로그를 저장하고, Grafana에서 이 세 신호를 통합 시각화하는 전체 스택을 Docker Compose로 구축했습니다. Exemplars를 통한 메트릭-트레이스 연결도 실제로 확인했습니다.

다음 장에서는 AI 서비스의 관측 가능성을 다룹니다. LLM 호출 추적, 토큰 사용량/비용 모니터링, AI 에이전트 행동 추적, LangChain/LlamaIndex와의 OTel 통합을 학습합니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#monitoring#observability

관련 글

인프라

9장: AI 서비스 관측 가능성

LLM 호출 추적, 토큰 사용량/비용 모니터링, AI 에이전트 행동 추적, LangChain/LlamaIndex OTel 통합을 통한 AI 관측 가능성을 학습합니다.

2026년 2월 24일·12분
인프라

7장: Collector 아키텍처와 배포

OTel Collector의 Receiver/Processor/Exporter 파이프라인, 핵심 프로세서 활용법, Kubernetes 환경에서의 DaemonSet/Deployment 배포를 학습합니다.

2026년 2월 20일·13분
인프라

10장: SLO 기반 알림 설계

SLI/SLO/에러 버짓의 개념을 정립하고, 번 레이트 알림(fast-burn/slow-burn), Prometheus 알림 규칙, Grafana 알림 채널을 설계합니다.

2026년 2월 26일·15분
이전 글7장: Collector 아키텍처와 배포
다음 글9장: AI 서비스 관측 가능성

댓글

목차

약 12분 남음
  • 학습 목표
  • 백엔드 아키텍처 개요
  • Jaeger — 분산 추적 백엔드
    • Jaeger의 주요 기능
    • Collector에서 Jaeger로 연동
    • Grafana Tempo — 차세대 트레이스 백엔드
  • Prometheus — 메트릭 백엔드
    • OTel Collector와 Prometheus 연동
    • PromQL 활용 예시
  • Grafana Loki — 로그 백엔드
    • LogQL 활용 예시
  • Grafana 통합 대시보드
    • 데이터 소스 설정
    • 신호 간 연결 흐름
  • Docker Compose 전체 스택 실습
    • OTel Collector 설정
    • 실행과 확인
  • Exemplars 실전 활용
    • Prometheus 설정
    • Grafana에서 Exemplar 확인
  • 정리