LabHub

블로그

관측 가능성의 현재 심화 가이드 — OpenTelemetry, Prometheus, eBPF, SLO/SLI, Continuous Profiling, Chaos Engineering까지 (2025)

TL;DR — 관측 가능성(Observability)은 2024-2025년 혁명의 한복판에 있다. OpenTelemetry가 CNCF의 두 번째로 활발한 프로젝트(Kubernetes 다음)가 되며 de facto 표준이 됐고, eBPF 기반 agentless instrumentation(Pixie, Beyla, Parca)이 코드 한 줄 안 바꾸고 full-stack 관측을 가능하게 만들었다. Continuous Profiling이 4번째 pillar로 공식화됐고, SLO/SLI 기반 알림은 Google SRE의 대중화로 알림 피로를 해결한다. 이 글은 "모르는 것을 알게 되는 기술"의 전 지형도 — 세 가지 pillar의 원리와 한계, Prometheus cardinality 지옥, OpenTelemetry context propagation, Honeycomb의 high-cardinality 혁명, Datadog/Grafana/New Relic SaaS 경쟁까지 — 원리와 실전을 모두 추적한다.

Monitoring vs Observability — 용어 정리부터

'모니터링(Monitoring)'과 '관측 가능성(Observability)'은 자주 혼용되지만 다르다:

2018년 Honeycomb의 Charity Majors가 제안한 정의: "Observability는 외부에서 관찰 가능한 신호만으로 시스템의 모든 내부 상태를 이해할 수 있는 정도". 제어 이론에서 빌려온 개념.

현대 분산 시스템은 수백 개 마이크로서비스, 수천 개 Pod, 수만 개 이벤트가 동시에 돌아간다. '알려진 대시보드 몇 개'로는 절대 부족 → 관측 가능성이 필요한 이유.

4 Pillars — Metrics, Logs, Traces, Profiles

2020년까지 '3 Pillars'였으나, 2023-2024년 Continuous Profiling이 4번째로 공식화.

Metrics — 집계된 수치

한계: cardinality(레이블 조합) 폭발 시 비용 기하급수. user_id를 레이블로 넣으면 사용자 수만큼 시리즈 증가.

Logs — 이벤트 기록

한계: 볼륨 거대, 검색 느림, 상관관계 추적 어려움.

Traces — 요청의 여정

한계: 100% sampling은 비용 폭발. Head-based/Tail-based sampling 트레이드오프.

Profiles — 코드 수준 성능

2024 혁명: eBPF로 무계측(no instrumentation) 프로파일링이 상시 가능.

이 4개의 관계

같은 문제를 4가지 각도에서 보는 것:

Exemplar로 연결: 특정 metric 포인트에 trace ID 첨부 → 급등한 지연시간 → 해당 trace → 해당 span → 해당 profile.

Prometheus — 사실상 표준

2012년 SoundCloud에서 시작, 2016년 CNCF. Kubernetes 다음으로 중요한 CNCF 프로젝트.

Pull vs Push

Prometheus는 pull 모델 — 주기적으로 target을 scrape.

# prometheus.yml
scrape_configs:
- job_name: 'app'
  scrape_interval: 15s
  static_configs:
  - targets: ['app-1:8080', 'app-2:8080']

Data Model

metric_name{label1="v1", label2="v2"} value timestamp

PromQL — 시계열 대수학

# 1분 평균 QPS
rate(http_requests_total[1m])

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

# 서비스별 p99 latency
histogram_quantile(0.99, 
  sum(rate(http_request_duration_seconds_bucket[5m])) by (service, le))

# 지난 1시간과 비교 (이상 감지)
rate(http_requests_total[5m]) 
  / rate(http_requests_total[5m] offset 1h)

Cardinality 지옥

Prometheus는 각 레이블 조합을 별도 시계열로 저장. 레이블이 N개이고 각각 M개 값이면 최악 M^N 시리즈.

❌ 나쁜 예 — user_id가 레이블
http_requests_total{user_id="42", endpoint="/api/users"} 1

이러면 1백만 유저 × 100 endpoint = 1억 시리즈. Prometheus 메모리 폭발.

✅ 좋은 예 — user_id는 레이블 아님
http_requests_total{endpoint="/api/users", tier="free"} 1

조언: 레이블 값은 bounded (enum 수준)이어야. user_id, trace_id, session_id는 logs/traces로.

스케일 아웃 — Thanos, Cortex, Mimir

단일 Prometheus는 보통 수백만 시리즈까지. 그 이상은:

Grafana

시각화 de facto. 2024년 Scenes 프레임워크로 대시보드 동적 생성, Sceneapp으로 앱 제작.

OpenTelemetry — 2024년 de facto 표준

OpenTelemetry(OTel)는 2019년 OpenTracing + OpenCensus 합병으로 탄생. 2024년 기준 CNCF 2번째로 활발한 프로젝트.

왜 OpenTelemetry가 이겼나

이전: Datadog agent, New Relic agent, Jaeger client, Zipkin client 등 벤더 락인. 바꾸려면 코드 전부 재계측.

OTel: 표준 API + SDK + 프로토콜(OTLP). 코드는 OTel로 쓰고, 백엔드는 원하는 것으로 (Jaeger, Tempo, Datadog, Honeycomb...).

아키텍처

[App + OTel SDK]
OTLP (gRPC/HTTP)
[OTel Collector]
 ┌───┼────────────┐
 ↓   ↓            ↓
Prometheus  Jaeger/Tempo  Datadog/Honeycomb

OTel Collector는 중간 허브: receiver → processor → exporter.

# otel-collector.yaml
receivers:
  otlp:
    protocols: { grpc: {}, http: {} }
  prometheus:
    config:
      scrape_configs:
      - job_name: 'app'
        static_configs:
        - targets: ['app:8080']

processors:
  batch:
    timeout: 10s
  memory_limiter:
    limit_mib: 512
  tail_sampling:
    decision_wait: 30s
    policies:
    - { name: errors, type: status_code, status_code: { status_codes: [ERROR] } }
    - { name: slow, type: latency, latency: { threshold_ms: 1000 } }

exporters:
  otlphttp/tempo:
    endpoint: http://tempo:4318
  prometheus:
    endpoint: "0.0.0.0:8889"
  otlp/datadog:
    endpoint: otel.datadog.com:443

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, tail_sampling, batch]
      exporters: [otlphttp/tempo, otlp/datadog]

Auto-instrumentation

# Java
java -javaagent:opentelemetry-javaagent.jar -jar app.jar

# Python
opentelemetry-instrument python app.py

# Node.js
node --require @opentelemetry/auto-instrumentations-node app.js

# Go — ebpf-based (Beyla, 2024)
beyla --exec app

Go는 런타임 instrumentation이 약해 컴파일 시 수동 계측이 주였으나, Grafana Beyla(eBPF)가 agentless auto-instrumentation 제공.

Semantic Conventions

2024년 1.0으로 안정화. 속성 이름을 표준화 → 교차 벤더 분석 가능.

http.request.method = "GET"
http.response.status_code = 200
server.address = "api.example.com"
db.system = "postgresql"
db.statement = "SELECT * FROM users WHERE id = $1"
messaging.system = "kafka"
messaging.destination.name = "orders"

Distributed Tracing — span 전파의 과학

Span 모델

Trace: 전체 요청 단위
 ├─ Span A: POST /checkout (1000ms)
 │   ├─ Span B: validate_cart (50ms)
 │   ├─ Span C: create_order (200ms)
 │   │   └─ Span D: db INSERT (150ms)
 │   └─ Span E: notify_payment (700ms)
 │       └─ Span F: HTTP POST /stripe (650ms)

각 Span:

W3C Trace Context

2020년 W3C 표준. HTTP 헤더로 trace 전파:

traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
             │  │                                 │                │
             │  trace-id (16바이트 hex)            span-id          flags
             version
tracestate: vendor1=abc,vendor2=xyz

모든 마이크로서비스가 이 헤더를 전달/추가해야 trace가 끊어지지 않음.

Sampling 전략

100% 샘플링은 비용 폭발. 전략:

  1. Head-based — 시작 시점에 결정 (예: 1% 랜덤)

    • 장점: 간단
    • 단점: 에러 trace 놓칠 수 있음
  2. Tail-based — 모든 span 수집 후 결정

    • 장점: 에러/느린 trace 100% 유지
    • 단점: 버퍼 필요 (OTel Collector)
  3. Adaptive — 트래픽에 따라 동적

Jaeger vs Tempo vs Zipkin

Honeycomb의 high-cardinality 혁명

Charity Majors(전 Parse/Facebook)가 2016년 창업. 'metrics + logs' 패러다임을 wide events로 대체.

Wide Events란

로그 1줄에 모든 컨텍스트를 다 넣음:

{
  "timestamp": "2025-04-15T10:00:00Z",
  "service": "checkout",
  "user_id": 42,
  "user_tier": "premium",
  "cart_total": 99.99,
  "cart_items": 3,
  "payment_method": "stripe",
  "stripe_account": "acct_xyz",
  "response_time_ms": 450,
  "db_queries": 5,
  "cache_hits": 12,
  "cache_misses": 3,
  "region": "us-east-1",
  "availability_zone": "us-east-1a",
  "pod_name": "checkout-7d8f",
  "error": null,
  "trace_id": "abc...",
  "...": "..."
}

Honeycomb은 이를 column-store에 넣어 임의 attribute로 그룹화/필터링. cardinality 제한 없음.

BubbleUp — 자동 이상 감지

"이 지연시간 급증이 왜?" → Honeycomb이 자동으로 dimension별 차이를 계산. "premium user + stripe + eu-west-1이 99% 공통"같은 발견.

이 접근은 2024년 Datadog, New Relic, Grafana Cloud에 영향. Wide events 기반 분석이 주류화 중.

Loki — Prometheus for Logs

Grafana Labs가 2018년 공개. "로그를 인덱싱하지 말고 레이블만 인덱싱" 철학.

# Promtail 설정
scrape_configs:
- job_name: system
  static_configs:
  - targets: [localhost]
    labels:
      job: varlogs
      __path__: /var/log/*log

LogQL

# 에러 로그 필터
{job="app"} |= "ERROR"

# 정규식 + JSON 파싱
{job="app"} |~ "user_id=\d+" | json | response_time > 1000

# 로그에서 metric 생성
sum(rate({job="app"} |= "ERROR"[5m])) by (service)

Loki vs Elastic vs CloudWatch

도구스토리지비용검색 속도
LokiS3 + 인덱스 최소저렴중간
Elastic자체 인덱스 전체비쌈빠름
CloudWatch LogsAWS 관리중간느림
Grafana Cloud LogsLoki 기반저렴중간
Datadog LogsSaaS매우 비쌈빠름

eBPF Observability — agentless 혁명

2020년대 초 폭발. 커널 레벨에서 시스템 콜 + 네트워크를 훅킹해 앱 변경 없이 메트릭/trace/profile 수집.

Pixie (New Relic 인수)

Beyla (Grafana Labs, 2023)

Parca / Pyroscope

Tetragon (Isovalent)

Falco

Continuous Profiling — 4번째 pillar

기존 profiling은 "특정 시점 30초 수집". Continuous Profiling은 모든 production 24/7.

Pyroscope 사용 예

import "github.com/grafana/pyroscope-go"

pyroscope.Start(pyroscope.Config{
    ApplicationName: "checkout",
    ServerAddress:   "http://pyroscope:4040",
    ProfileTypes:    []pyroscope.ProfileType{
        pyroscope.ProfileCPU,
        pyroscope.ProfileAllocObjects,
        pyroscope.ProfileAllocSpace,
    },
})

Flame Graph — 시각화

[total 10s]
├─ main (10s)
│   ├─ handleRequest (6s)
│   │   ├─ dbQuery (4s)
│   │   └─ jsonMarshal (2s)
│   └─ background (4s)
│       └─ backgroundWorker (4s)
│           └─ httpClient (3.5s)

가로가 시간. 직관적으로 '뚱뚱한' 함수가 병목.

pprof 호환

Go/Java/Python/Ruby/Node.js가 모두 pprof profile 생성 → Pyroscope/Parca/Grafana Cloud/Google Cloud Profiler 어디나 이식 가능.

SLO/SLI/Error Budget — Google SRE의 대중화

2003년 Google이 내부 도입, 2016년 'Site Reliability Engineering' 책으로 대중화.

용어

Error Budget의 힘

이게 제품팀과 SRE팀의 협상 기반. '안정성 vs 속도' 갈등을 수치로 해소.

Multi-window, Multi-burn-rate 알림

# 1시간 burn rate 14.4x 초과 (2% SLO 사용률)
(1 - sum(rate(http_requests_total{status=~"5.."}[1h])) 
   / sum(rate(http_requests_total[1h]))) 
< 0.999 * (1 - 0.02)
and
# + 5분 burn rate 14.4x (빠른 감지)

장점: noisy alert 급감. Google SRE Workbook Chapter 5.

Sloth, Pyrra, OpenSLO

SLO 표준화 도구. 2024년 OpenSLO 1.0 → 벤더 간 이식성.

Alerting 철학 — Page-worthy vs Dashboard

나쁜 알림

좋은 알림 (Page-worthy)

3-tier 알림

  1. Page (전화/SMS) — 즉시 조치. SLO burn rate 기반.
  2. Ticket — 업무 시간 조치. 추세 이상.
  3. Dashboard/Digest — 정보 확인용.

Runbook

모든 알림은 runbook URL 필수. "이 알림이 뜨면 뭘 해야 하는가?"가 문서화 안 되면 알림 가치 0.

Service Level vs System Level

SLI = 좋은 이벤트 / 전체 이벤트

SLI 예시:
- availability: 200-599 중 non-5xx 비율
- latency: 500ms 이내 비율
- correctness: 비즈니스 로직 성공 비율 (e.g. 결제 성공)
- freshness: 데이터 최신성 (e.g. 1분 이내 업데이트된 row)

User-journey SLO — 단일 API 아니라 "로그인 → 상품 검색 → 결제" 전체.

Chaos Engineering — 의도적으로 고장내기

Netflix가 2010년대 Chaos Monkey로 대중화. "고장을 의도적으로 일으켜 복원력 검증".

원칙 (Principles of Chaos)

  1. 정상 상태 정의
  2. 정상 상태가 유지될 가설 수립
  3. 실제 사건 시뮬레이션 (서버 다운, 네트워크 지연, CPU 부하)
  4. 가설 검증 — 실패 시 개선점

도구

# Chaos Mesh 예시: Pod 무작위 종료
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-kill
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces: [prod]
    labelSelectors: { app: checkout }
  scheduler:
    cron: "@every 1h"

Game Day

월 1-2회 의도적 장애 훈련. 신입 엔지니어의 운영 훈련에 필수.

SaaS 비교 — Datadog vs Grafana vs Honeycomb vs New Relic

도구강점약점가격
Datadog올인원, 500+ integration, APM 최강비쌈 (월 수천~수만 달러), lock-inHost당 $15-23/월 + 사용량
Grafana CloudOSS 기반, 자체 호스팅 가능, 오픈 표준UX 덜 세련, APM 약함Free tier, $8/월부터
Honeycombhigh-cardinality 분석, BubbleUpMetrics 약함Event 단위 $$
New RelicPricing 유저 기반, Pixie(eBPF)UI 구식사용자당 $10-25/월
DynatraceAI 기반 자동 분석, 엔터프라이즈비쌈, lock-in견적 기반
Splunk로그/SIEM 강점매우 비쌈, UI 구식견적 기반
Elastic Observability오픈소스 가능, 전문검색자체 운영 복잡Cloud $95/월부터

2024-2025 트렌드: 대기업은 Datadog 의존도 축소 (비용), OpenTelemetry + Grafana Cloud + Honeycomb 혼합 선호.

Datadog 비용 폭발 사례

2023년 Coinbase가 Datadog에 연 $65M 썼다는 공시가 화제. 이후 여러 기업이 OTel + Grafana로 이전.

2025년 주목할 트렌드

AI for Observability

Digma, OpenSearch, Quickwit

Kubernetes-native

Cost Observability

실전 체크리스트 (2025)

  1. OpenTelemetry 채택 — SDK + Collector + OTLP export
  2. 3 pillars 수집 — Prometheus(metrics), Loki/Elastic(logs), Tempo/Jaeger(traces)
  3. Exemplars 연결 — metric → trace
  4. Cardinality 감사 — 분기별 비용 검토, 불필요 레이블 제거
  5. Structured logging 강제 — JSON, trace_id 필수 포함
  6. Tail-based sampling — 에러/slow 100%, 나머지 1%
  7. SLO 정의 — 핵심 user journey 3-5개
  8. Error Budget alert — burn rate 기반 멀티 윈도우
  9. Runbook per alert — URL 없는 알림 금지
  10. Continuous profiling — production 상시
  11. Chaos game day — 월 1회
  12. 비용 관측 — OpenCost + 월 리포트

10가지 흔한 안티패턴

  1. 레이블에 user_id/session_id — cardinality 폭발
  2. 로그를 metric 대용으로 — 비싸고 느림
  3. 100% trace sampling — 비용 폭발, tail-based 써라
  4. 알림 200개/일 — alert fatigue, SLO 기반으로 재설계
  5. CPU/메모리만 알림 — 증상 아닌 원인, 사용자 영향 모름
  6. 단일 벤더 all-in — 이전 비용 마이그레이션 지옥
  7. 모니터링 = 관측 가능성 오해 — 대시보드만 늘어남
  8. Profiling = 개발 시 1회 오해 — 상시 필요
  9. 자체 호스팅 Prometheus 10억 시리즈 — Thanos/Mimir 필수
  10. dashboard 수백 개 — 아무도 안 봄, SLO 기반으로 통합

다음 글 예고 — "WebAssembly의 다음 10년" — 브라우저를 넘어선 WASM의 서버·엣지·플러그인 혁명

관측 가능성이 '시스템을 아는 기술'이라면, WebAssembly는 '어디서나 동작하는 이식성의 기술'이다. 2017년 브라우저 표준으로 출발한 WASM은 2024-2025년 서버(Fastly, Fermyon), 엣지(Cloudflare Workers, Deno Deploy), 플러그인(Envoy, Istio, Redpanda), 블록체인(Substrate, NEAR), AI(ONNX Runtime Web)까지 확장됐다. 놀라운 콜드 스타트(< 5ms), 모든 언어 지원, 강력한 샌드박싱으로 'Docker의 다음 단계'라 불린다.

다음 글에서는:

을 다룬다. '한 번 컴파일, 어디서나 실행'이라는 Java의 오래된 약속이 WASM으로 어떻게 현실이 됐는지, 그리고 Docker의 대체가 아니라 보완이 되는 이유를 추적한다.

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다