2 min read
OpenTelemetry 관측성 베이스라인
로그, 메트릭, 트레이스를 연결해 장애 원인 파악 시간을 줄이는 계측 기준

도입
장애 대응 속도는 로그 양이 아니라 컨텍스트 품질로 결정된다. OpenTelemetry를 도입해도 trace_id가 서비스 경계를 넘지 못하면 원인 분석 시간은 거의 줄지 않는다. 이 글은 최소한의 비용으로 추적 가능성을 확보하는 관측성 베이스라인을 제시한다.

문제 정의
관측성 도입이 실패하는 이유는 모든 신호를 한 번에 수집하려고 하기 때문이다.
- span 이름 규칙이 없어 대시보드가 쿼리 불가능한 문자열 모음이 된다.
- error 이벤트에 비즈니스 키가 없어 장애 영향 범위를 추적하지 못한다.
- 샘플링 정책이 고정되어 피크 시간에 중요한 trace가 누락된다.
초기에는 critical path 3개만 추적해도 충분하다. 대신 태그 표준과 ID 전파 규칙은 강하게 고정해야 한다.
핵심 개념
| 관점 | 설계 기준 | 검증 포인트 |
|---|---|---|
| Trace | 요청 단위 상관관계 | 서비스 경계별 span 연결률 |
| Metrics | SLO 중심 지표 | 오탐 경보 비율 |
| Logs | 구조화 로그 + trace_id | 원인 분석 소요 시간 |
| Sampling | 트래픽/오류 기반 동적 샘플링 | 비용 대비 신호 밀도 |
관측성은 수집이 아니라 설계다. 어떤 질문에 답하기 위해 데이터를 남기는지 먼저 정의하면 불필요한 수집 비용을 줄일 수 있다.
코드 예시 1: HTTP 서비스 트레이싱
import { trace } from "@opentelemetry/api";
const tracer = trace.getTracer("8space-api");
export async function tracedHandler(requestId: string, fn: () => Promise<unknown>) {
return tracer.startActiveSpan("http.request", async (span) => {
span.setAttribute("request.id", requestId);
span.setAttribute("service.name", "blog-api");
try {
const result = await fn();
span.setStatus({ code: 1 });
return result;
} catch (error) {
span.recordException(error as Error);
span.setStatus({ code: 2, message: "handler failed" });
throw error;
} finally {
span.end();
}
});
}
코드 예시 2: Collector 파이프라인
receivers:
otlp:
protocols:
http:
grpc:
processors:
batch:
attributes:
actions:
- key: deployment.environment
value: production
action: upsert
exporters:
prometheus:
otlphttp:
endpoint: https://otel.example.com/v1/traces
아키텍처 흐름
Mermaid diagram rendering...
트레이드오프
- 샘플링을 높이면 분석 품질은 좋아지지만 저장 비용이 빠르게 증가한다.
- 태그를 많이 넣으면 검색성은 좋아지지만 고카디널리티로 성능 저하가 발생할 수 있다.
- 초기 범위를 좁히면 도입이 빠르지만 비핵심 구간 장애는 별도 분석이 필요하다.
정리
OpenTelemetry 베이스라인은 완전한 계측이 아니라 운영 가능한 최소 표준을 먼저 만드는 일이다. ID 전파, 태그 규칙, 동적 샘플링을 고정하면 장애 대응 속도를 안정적으로 개선할 수 있다.
이미지 출처
- Cover: source link
- License: CC BY-SA 3.0 / Author: Unknown
- Note: Wikimedia Commons 무료 라이선스 이미지를 다운로드 후 1600px 기준 JPG로 최적화했습니다.