production 에서 무언가 잘못 됐다. 그런데 무엇이? 한 사용자만? 모두? DB? 외부 API? — 이 질문에 답하는 능력이 observability. 단순 monitoring (정해진 metric 만 보기) 과 달리, 사전에 정의 안 된 질문에도 답할 수 있어야 한다. 이 가이드는 3 pillars (logs · metrics · traces) 와 cardinality 의 본질을 정리한다.
Monitoring vs Observability — 의미 차이
Monitoring: 알려진 질문에 답
- CPU > 80% 이면 alert
- 5xx rate > 1% 이면 alert
- 미리 정해진 dashboard
Observability: 새 질문에 답할 수 있는 능력
- "왜 어제 11pm 의 latency 가 튀었나?"
- "이 user 의 요청이 어디서 실패했나?"
- "기능 X 출시 후 어느 endpoint 의 p99 가 변했나?"
→ 둘 다 필요. Monitoring 은 "사고 인지", Observability 는 "사고 진단".3 Pillars — Logs · Metrics · Traces
Logs — 무슨 일이 일어났는지의 기록
형식: 이벤트 (시점 + 컨텍스트)
{
"ts": "2026-05-25T14:32:01Z",
"level": "error",
"msg": "DB connection refused",
"host": "api-prod-3",
"user_id": "u_42",
"request_id": "req_abc123",
"stack": "..."
}
강점: rich context, 디버깅 정밀
약점: 부피 ↑↑ (TB 단위), 집계 비쌈, 분석 비용Metrics — 시간 시리즈의 숫자
형식: 시점 + 숫자 + label (집계 가능)
http_requests_total{method="POST", path="/login", status="200"} 1234
http_requests_total{method="POST", path="/login", status="500"} 5
강점: 작음 (이벤트당 ~bytes), 빠른 집계 (count/avg/p99), 대시보드 적합
약점: 사전 정의된 metric 만 가능, 개별 이벤트 detail XTraces — 요청의 여정
형식: span 들의 tree (시간 + 부모-자식)
trace abc123 (total 450ms)
├─ HTTP POST /login (450ms) service: api
│ ├─ DB query users (320ms) service: db
│ │ └─ INDEX scan (310ms) ← bottleneck!
│ └─ Redis SET session (15ms) service: cache
강점: 서비스 간 흐름 명확, 어디서 느린지 한눈에
약점: instrumentation 필요, 부피 ↑ (보통 sampling)Cardinality — observability cost 의 ceiling
cardinality = label 의 unique 값 조합 수
example 1 — 적음:
http_requests{method="GET|POST|...", status="200|400|500"}
→ method 5 × status 6 = 30 series
example 2 — 폭발:
http_requests{method, status, user_id, request_id}
→ user 100 만 × request 1억 = 10^11 series 😱
Prometheus 같은 시스템: cardinality × time series 가 storage cost
DataDog / Honeycomb 등 클라우드: cardinality 별 과금
→ "다 로그하기" 가 안 되는 이유 = cardinality 한도.
request_id 같은 high-cardinality 는 trace 또는 log 에 두고,
metric label 에는 두지 마라.각 pillar 의 적합 use case
| 질문 | 도구 |
|---|---|
| 지금 시스템 건강한가? | metrics (dashboard, alert) |
| 이 endpoint 의 p99 추세? | metrics |
| 이 요청이 왜 느렸나? | traces (해당 trace ID lookup) |
| 이 user 의 에러 원인? | logs (user_id filter) + trace |
| 어제 11pm 에 무슨 일? | logs (시간 + 컨텍스트 검색) |
| service A → B 의 latency 분포? | traces 집계 + metrics |
OpenTelemetry — 단일 표준
이전: 도구마다 다른 SDK
- DataDog SDK / New Relic agent / Honeycomb SDK / ...
- 도구 바꾸려면 모든 application 코드 변경
OpenTelemetry (CNCF, 2019+):
- logs / metrics / traces 의 통일된 spec + SDK
- exporter 만 바꾸면 backend (Jaeger / Tempo / DataDog / ...) 교체
→ vendor lock-in 해소. instrumentation 한 번, 출력처 자유.흔한 함정
- "다 로그하면 된다" — 부피 폭발 + 비용 폭발 + 신호 vs 노이즈. 의도적 sampling + structured.
- average 만 보고 fine 이라 판단 — average 가 OK 인데 p99 가 2초면 1% 사용자 고통. histogram + percentile 필수.
- metric label 에 user_id / request_id 박기 — cardinality 폭발. 그것들은 trace / log 에 두기.
- alert 너무 많음 — 새벽 3시 page 잡음 → on-call burnout. SLO 기반 alert (SLI/SLO 가이드 참조).
- trace 가 production 영향 — sampling 안 하면 매 요청에 ms overhead. head sampling (1%) 또는 tail sampling (errors 100%).
마무리
Observability 는 단일 도구가 아니라 능력 — 사전에 정의 안 된 질문에 답할 수 있는 능력. 3 pillars 가 보완 (logs = 상세, metrics = 집계, traces = 흐름). cardinality 가 비용 ceiling.
시작: structured logging + 기본 metrics (RED / USE) + 핵심 path 의 tracing. 모든 service 에 full instrumentation 보다 incremental.