최소 관측 — 로그·메트릭·트레이스
관측 (observability) 이라는 단어가 풀스택 도입을 떠올리게 만들지만, 작은 시스템부터 풀 스택을 도입하면 운영 비용이 가치를 앞지르기 쉽습니다.
목차
관측 (observability) 이라는 단어가 풀스택 도입을 떠올리게 만들지만, 작은 시스템부터 풀 스택을 도입하면 운영 비용이 가치를 앞지르기 쉽습니다.
1. 3 Pillars
관측의 자리는 흔히 세 기둥으로 정리됩니다.
| 기둥 | 무엇을 본다 | 흔한 도구 |
|---|---|---|
| 로그 (Logs) | 사건·메시지의 시간순 기록 | 표준 출력 · 파일 · Loki · ELK · CloudWatch |
| 메트릭 (Metrics) | 시간 윈도의 수치 (요청 수·지연·에러율) | Prometheus · Datadog · CloudWatch Metrics |
| 트레이스 (Traces) | 한 요청이 시스템을 거친 경로 | Jaeger · Tempo · Honeycomb · Datadog APM |
세 기둥은 서로 보완합니다. 메트릭이 이상을 알리고, 로그가 그 시점의 사건을 보여주고, 트레이스가 그 요청이 어디서 느려졌는지 보여줍니다.
2. OpenTelemetry
CNCF 의 프로젝트로 2019 년에 OpenTracing (2016) + OpenCensus (2017) 의 합병으로 출발했습니다. 사이트는 opentelemetry.io. 표준 SDK · API · 와이어 포맷 (OTLP) 을 정의해 벤더 종속을 줄입니다.
핵심 모양:
- 애플리케이션은 OpenTelemetry SDK 로 신호를 만듭니다 (traces · metrics · logs).
- OTel Collector (또는 직접) 가 신호를 받아 백엔드로 보냅니다.
- 백엔드 (Tempo · Jaeger · Datadog 등) 는 시각화·검색을 제공합니다.
벤더 락인을 피하려는 자리에서 자주 거론됩니다.
3. 로그의 결
- 구조화 로그 (JSON) — 키-값으로 적어 검색·집계가 가능하게.
- 상관 ID (correlation id / trace id) — 한 요청을 구분하는 키를 모든 관련 로그에 함께 적습니다.
- 레벨 — DEBUG · INFO · WARN · ERROR · FATAL.
- 샘플링 — 너무 많은 로그는 비용·노이즈가 됩니다. 중요한 자리만 또는 비율 샘플링.
{
"ts": "2026-04-25T01:23:45Z",
"level": "ERROR",
"service": "api",
"trace_id": "0a1b2c...",
"msg": "DB query timeout",
"query": "SELECT ... LIMIT 10",
"elapsed_ms": 5021
}
4. 메트릭의 결
- Counter — 단조 증가 (요청 수·에러 수).
- Gauge — 순간 값 (현재 메모리·연결 수).
- Histogram — 분포 (지연 시간) — p50 · p95 · p99 같은 분위수.
- Summary — 분위수를 클라이언트가 미리 계산.
p99 지연이 평균보다 더 의미 있는 자리가 많습니다. 평균만 보면 꼬리(tail) 가 가린 사용자 경험이 보이지 않습니다.
5. 트레이스의 결
- Span — 한 작업의 시작·끝을 가진 단위.
- Trace — 한 요청에 속한 스팬의 트리.
- 컨텍스트 전파 — 스팬 ID 를 HTTP 헤더 (
traceparent) · 메시지 헤더로 전달. - 샘플링 — 매 요청을 트레이스로 남기면 비쌉니다. 비율·헤드·테일 샘플링.
W3C Trace Context · B3 같은 헤더 표준이 있고 OTel 이 W3C 를 기본으로 합니다.
6. Grafana 스택
- Grafana — 시각화.
- Prometheus — 메트릭 수집·저장.
- Loki — 로그 저장.
- Tempo — 트레이스 저장.
- Mimir — 대규모 메트릭 (분산 Prometheus 호환).
오픈소스이고 자체 호스팅이 가능하지만 5~6 개 서비스를 운영·업그레이드·백업해야 한다는 의미입니다.
7. SaaS 도구들
| 도구 | 결 |
|---|---|
| Datadog | 종합 APM · 인프라 · 로그 · 보안. 비용은 사용량에 따라 빠르게 자람. |
| New Relic | 비슷한 결의 종합 APM. 사용자 단위 라이선스. |
| Honeycomb | 트레이스·고차원 이벤트 중심. high-cardinality 질의 강조. |
| Sentry | 에러 추적 우선, 트레이싱·세션 추가. |
| Logtail · Better Stack · Axiom | 로그 SaaS 의 신규 자리. |
선택은 다음의 균형입니다:
- 운영 인력의 여유.
- 비용 예측 가능성.
- 데이터 보존 기간·규제.
- 통합 폭 (언어·프레임워크·인프라).
8. 최소 관측 — 4 단계
작은 시스템·단일 서버에서 시작하는 결입니다.
1 단계 — 구조화 로그 + 헬스체크
- 모든 서비스 로그를 JSON 으로.
/health·/ready엔드포인트.- 외부 uptime 모니터 (UptimeRobot · BetterStack · Cronitor) 가 이 엔드포인트를 확인하고 알림.
이 한 단계만으로도 "서비스가 죽으면 안다" 는 자리가 채워집니다.
2 단계 — 에러 추적
- Sentry (또는 비슷한 서비스) 를 붙여 예외를 자동 전송.
- 스택 트레이스·release · 사용자 컨텍스트가 함께 모입니다.
- 비용 예측 가능한 자리.
3 단계 — 핵심 메트릭
- 요청 수 · 에러율 · p95 지연 정도를 노출.
- Prometheus + 작은 Grafana, 또는 클라우드 매니지드 메트릭.
- 알림은 핵심 지표 1~2 개로 시작.
4 단계 — 트레이싱
- 다중 서비스 호출이 늘면 트레이스의 가치가 커집니다.
- OpenTelemetry SDK + 백엔드 (Tempo · Jaeger · SaaS) 결합.
- 샘플링으로 비용 통제.
9. 어떤 정보가 결국 보여야 하나
각 단계의 이름·도구가 다르더라도 다음 정보가 결국 보여야 합니다.
- 지난 1 시간의 에러 수와 p95 지연.
- 지금 진행 중인 알람.
- 어떤 사용자·요청이 영향을 받았는가.
10. 자주 걸리는 자리
풀 스택 조기 도입 — 작은 시스템에 5 개 서비스를 띄우면 관측 자체의 운영 부담이 본 시스템보다 커집니다. 단계적 도입이 안전합니다.
로그에 비밀 — 패스워드·토큰·개인정보가 로그에 남습니다. 마스킹 라이브러리·필터로 막습니다.
카디널리티 폭주 — 메트릭 라벨에 사용자 ID·요청 ID 를 넣으면 시계열 수가 폭증합니다.
트레이스 누락 — 비동기·메시지 큐 경로에서 컨텍스트 전파가 끊어지는 자리. 명시 전파.
알림 피로 — 알람이 너무 많으면 모두 무시됩니다. 핵심 1~3 개로 시작 + 점진 추가.
샘플링의 의미 — 1% 샘플링 트레이스는 디버그용으로 충분할 때가 많지만 드문 에러를 놓칩니다. 헤드·테일 샘플링 결정.
시간 동기화 — 서버 간 시간이 어긋나면 트레이스·로그 상관이 어긋납니다. NTP.
벤더 종속 — SaaS 의 자체 SDK 만 쓰면 이전이 어렵습니다. OpenTelemetry 같은 표준 인터페이스 위에서 구성합니다.
하고픈 말
관측은 운영 사고 후에야 가치가 보이는 자리입니다. 그래도 풀 스택을 한 번에 들이는 일은 운영 부담만 키웁니다. 1 단계 구조화 로그 + 헬스체크부터 시작해 사고가 부족한 자리만 다음 단계로 가는 흐름이 가장 안전합니다.
Next
- github-actions
- vitest-pytest-infra
OpenTelemetry · W3C Trace Context · Prometheus · Grafana · Loki · Sentry · Charity Majors 글 을 참고합니다.
quality 카테고리의 다른 글
카테고리 전체 보기 →관련 글
Bounded RED 메트릭과 SLO를 같은 질문에 연결하기
관측성은 데이터를 많이 쌓는 일이 아니라 장애 질문에 답하는 일입니다. Rate·Errors·Duration을 route template로 수집하고 request context로 로그·비동기 작업과 연결합니다.
필수 readiness와 선택 capability를 분리하기
프로세스가 살아 있다는 사실, 핵심 검색 요청을 처리할 준비가 됐다는 사실, 선택 기능이 모두 정상이라는 사실은 서로 다릅니다. 하나의 ready 값에 전부 넣으면 선택 모델 장애가 전체 재시작으로 이어지고, 핵심 DB 장애를 liveness가 가립니다.