본문으로 건너뛰기
김신건의 로그

[Observability] Prometheus: pull 기반 메트릭, PromQL

· 수정 · 📖 약 2분 · 717자/단어 #prometheus #observability #metrics #devops
Prometheus, PromQL, scrape, exporter, Alertmanager, Thanos, Mimir, recording rule

정의

Prometheus = pull 기반 시계열 metric 시스템. PromQL 로 쿼리. CNCF graduated. 2026 클라우드 네이티브 메트릭 표준.

아키텍처

flowchart LR
    App1[App + /metrics] -.HTTP GET.-> Prom[Prometheus]
    App2[App + /metrics] -.HTTP GET.-> Prom
    NodeEx[node-exporter] -.HTTP GET.-> Prom
    KSM[kube-state-metrics] -.HTTP GET.-> Prom
    Prom --> TSDB[(Time Series DB)]
    Prom --> AM[Alertmanager]
    AM --> Slack[Slack / PagerDuty / Email]
    Prom --> Grafana

Pull 모델: Prometheus 가 각 target 의 /metrics 정기 scrape. Push 가 아닌 이유: target healthy 자동 확인, scrape interval 통제.

Exposition Format

# HELP http_requests_total Total HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200",path="/api/users"} 1234
http_requests_total{method="POST",status="201",path="/api/orders"} 567

# HELP http_request_duration_seconds Request duration
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.1"} 5000
http_request_duration_seconds_bucket{le="0.5"} 5800
http_request_duration_seconds_bucket{le="1.0"} 5900
http_request_duration_seconds_bucket{le="+Inf"} 6000
http_request_duration_seconds_sum 412.5
http_request_duration_seconds_count 6000

4가지 메트릭 타입

타입의미
Counter단조 증가requests_total
Gauge임의 변동memory_usage_bytes
Histogram분포 (bucket)request_duration_seconds
Summaryquantile (클라이언트 계산)request_duration_quantile

PromQL 예시

# 요청률 (5분)
rate(http_requests_total[5m])

# 에러 비율
sum(rate(http_requests_total{status=~"5.."}[5m]))
  / sum(rate(http_requests_total[5m]))

# 평균 응답 시간
rate(http_request_duration_seconds_sum[5m])
  / rate(http_request_duration_seconds_count[5m])

# p95 latency (histogram_quantile)
histogram_quantile(0.95,
  sum by (le, service) (rate(http_request_duration_seconds_bucket[5m]))
)

# 메모리 사용량 (gauge)
process_resident_memory_bytes

# CPU 사용률
rate(process_cpu_seconds_total[1m])

# 가용성 (up)
avg_over_time(up{job="api"}[5m])

Exporter

Exporter메트릭
node-exporterLinux node (CPU, RAM, disk, network)
kube-state-metricsK8s 객체 상태
cAdvisorcontainer metric (K8s 기본 포함)
postgres_exporterPG 통계
redis_exporterRedis
blackbox_exporterHTTP/TCP probe
nginx-exporternginx

4 Golden Signals (Google SRE)

flowchart TD
    G[4 Golden Signals]
    G --> Lat[Latency]
    G --> Tra[Traffic]
    G --> Err[Errors]
    G --> Sat[Saturation]

모든 서비스 대시보드의 기본 4. 이 4 가지면 대부분의 문제 발견.

Alertmanager

# Alert rule
groups:
  - name: api
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m]))
            / sum(rate(http_requests_total[5m])) > 0.05
        for: 5m
        labels: { severity: page }
        annotations:
          summary: "5xx rate > 5%"
# Alertmanager 설정
route:
  group_by: [alertname, severity]
  receiver: slack
  routes:
    - match: { severity: page }
      receiver: pagerduty
receivers:
  - name: slack
    slack_configs:
      - api_url: https://hooks.slack.com/...
  - name: pagerduty
    pagerduty_configs:
      - service_key: ...

Long-Term Storage

Local TSDBThanosMimirCortex
Retention15일 기본무제한 (S3)무제한무제한
HA없음있음있음있음
Multi-tenancy없음있음있음있음

수년 retention + 다중 cluster = Thanos / Mimir.

Recording Rule

- record: job:http_requests:rate5m
  expr: sum by (job) (rate(http_requests_total[5m]))

자주 쓰는 쿼리 결과 미리 계산. 대시보드 속도 ↑.

흔한 함정

WARNING

  1. Label cardinality 폭증 = user_id, request_id 같은 고유 값 을 label 로. 메모리 / disk 폭발.
  2. rate()짧은 range = scrape interval 보다 작으면 NaN.
  3. Counter reset 인식 못함 = rate() 가 자동. increase() 와 차이.
  4. Push 가 필요한 경우 = Pushgateway 사용 (batch job 등). 일반 service 는 pull.

Prometheus Operator / ServiceMonitor

Kubernetes 환경에서 kube-prometheus-stack (helm chart) 가 표준.

# ServiceMonitor: app 의 /metrics 를 자동 scrape
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: api
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      app: api
  endpoints:
    - port: http
      path: /metrics
      interval: 30s

prometheus.io/scrape: "true" annotation 방식은 레거시. Operator 환경에서는 ServiceMonitor / PodMonitor 를 사용.

Pushgateway (Batch Job 메트릭)

flowchart LR
    Job["Batch Job (짧은 수명)"] -->|push metrics| PG[Pushgateway]
    PG -.scrape.-> Prom[Prometheus]
    Prom --> Grafana

일반 service = pull. Batch job 처럼 짧게 실행 후 종료 = Pushgateway push.

WARNING

Pushgateway 는 SPOF: job 실패해도 metrics 가 남음. TTL 설정 또는 job 완료 후 delete API 호출 필수.

PromQL 핵심 함수

함수설명예시
rate(v[d])초당 평균 변화율rate(http_requests_total[5m])
irate(v[d])순간 변화율 (최근 2점)스파이크 민감 탐지
increase(v[d])범위 내 총 증가량increase(errors_total[1h])
sum by(label)레이블로 집계sum by (service)
topk(n, v)상위 N 시리즈topk(5, rate(rps[5m]))
absent(v)시리즈 없을 때 1 반환서비스 다운 감지
histogram_quantilebucket 에서 quantile 계산p99 latency
avg_over_time시간 범위 평균가용성 계산

Histogram vs Summary

항목HistogramSummary
다중 인스턴스 집계가능 (서버 집계)불가 (클라이언트 계산)
정확도bucket 오차 존재정확
quantile 변경재배포 없이 변경 가능재배포 필요
권장 상황대부분, 다중 인스턴스단일 인스턴스 정확 측정

IMPORTANT

인스턴스 여러 개 = Histogram 필수. Summary quantile 은 인스턴스 간 집계 불가.

Long-term Storage 선택

flowchart LR
    Prom[Prometheus] -->|remote_write| TH[Thanos / Mimir]
    TH --> S3[(S3: 무제한)]
    TH --> GQ["Grafana (통합 쿼리)"]
방식설명
Federation상위 Prometheus 가 하위 scrape (레거시)
Remote WritePrometheus → 외부 저장소 전송 (표준)
Agent Modescrape + remote write 만, local TSDB 없음
# Remote Write (Thanos Receiver)
remote_write:
  - url: http://thanos-receive:19291/api/v1/receive
    queue_config:
      max_samples_per_send: 10000

관련 위키

이 글의 용어 (5개)
[AWS] CloudWatch: 메트릭, 로그, 알람cloud
정의 CloudWatch = AWS 의 모니터링 + 로그 + 알람 통합 서비스. 메트릭 수집, 로그 집계, 대시보드, 알람, 이상 감지를 하나의 서비스에서 제공. 사용 상황 | …
[K8s] Pod: 컨테이너의 최소 단위, sidecar, lifecyclekubernetes
정의 Pod = K8s 의 가장 작은 배포 단위. 1개 이상의 컨테이너 + 공유 네트워크 + 공유 스토리지. [!IMPORTANT] Pod 는 컨테이너의 wrapping 이 아니…
[Observability] OpenTelemetry: 표준화된 trace/metric/logdevops
정의 OpenTelemetry (OTel) = observability 의 vendor-neutral 표준. CNCF. trace + metric + log 의 SDK + pro…
[Observability] SLI / SLO / SLA / Error Budgetdevops
정의 | | 의미 | |---|---| | SLI (Indicator) | 측정 값 (예: 5xx 비율) | | SLO (Objective) | 목표 (예: 99.9% 가용성) …
[Voice AI] P50/P95/P99: latency 분포와 SLOdevops
정의 P50 / P95 / P99 = latency 분포의 분위수. 평균은 outlier 에 가려져 무의미. 음성 에이전트의 사용자 경험 은 p95/p99 가 결정. [!IMPO…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기