상위: OpenTelemetry
요약
OpenTelemetry는 Traces, Metrics, Logs 세 가지 텔레메트리 신호(Signal)를 정의한다. 각 신호는 시스템의 다른 측면을 관찰하며, Context Propagation을 통해 서로 상관관계를 맺는다.
Traces (분산 추적)
요청이 분산 시스템을 통과하는 전체 경로를 추적한다.
구성 요소
- Trace: 하나의 요청에 대한 전체 경로. 여러 Span의 집합
- Span: 하나의 작업 단위. 이름, 시작/종료 시간, 속성(Attributes), 이벤트(Events), 상태(Status)를 가짐
- SpanContext: Trace ID + Span ID + Trace Flags. 서비스 간 전파되는 핵심 정보
Span 계층 구조
Trace (trace_id: abc123)
├── Span A: "HTTP GET /api/orders" (Root Span)
│ ├── Span B: "DB Query: SELECT..." (Child Span)
│ └── Span C: "HTTP POST /payment" (Child Span)
│ └── Span D: "Process Payment" (Grandchild Span)
예시 (Python)
from opentelemetry import trace
tracer = trace.get_tracer("order-service")
with tracer.start_as_current_span("process_order") as span:
span.set_attribute("order.id", "12345")
span.set_attribute("order.amount", 99.99)
with tracer.start_as_current_span("validate_payment"):
# 결제 검증 로직
pass
with tracer.start_as_current_span("save_to_db"):
# DB 저장 로직
span.add_event("order_saved", {"db.table": "orders"})
Span 종류 (SpanKind)
| Kind | 설명 | 예시 |
|---|---|---|
SERVER | 서버가 수신한 요청 | HTTP 핸들러 |
CLIENT | 외부 서비스 호출 | HTTP/gRPC 클라이언트 |
PRODUCER | 메시지 생산 | Kafka Producer |
CONSUMER | 메시지 소비 | Kafka Consumer |
INTERNAL | 내부 작업 | 비즈니스 로직 |
Metrics (지표)
시간에 따른 수치 측정값을 기록한다. 시스템 상태를 집계된 형태로 파악할 때 사용한다.
Instrument 종류
| Instrument | 설명 | 예시 |
|---|---|---|
| Counter | 단조 증가 값 | 총 요청 수, 에러 수 |
| UpDownCounter | 증감 가능 값 | 활성 연결 수 |
| Histogram | 분포 측정 | 응답 시간, 요청 크기 |
| Gauge | 특정 시점 값 | CPU 사용률, 메모리 |
예시 (Python)
from opentelemetry import metrics
meter = metrics.get_meter("order-service")
# Counter: 주문 수
order_counter = meter.create_counter(
name="orders.total",
description="Total number of orders",
unit="1"
)
# Histogram: 처리 시간
latency_histogram = meter.create_histogram(
name="orders.duration",
description="Order processing duration",
unit="ms"
)
def process_order(order):
order_counter.add(1, {"status": "processing"})
start = time.time()
# ... 처리 로직
duration = (time.time() - start) * 1000
latency_histogram.record(duration, {"endpoint": "/orders"})
Logs (로그)
타임스탬프가 찍힌 텍스트 기록. OTel은 기존 로깅 라이브러리(Python logging, Log4j 등)와 통합하여, 로그에 Trace ID/Span ID를 자동으로 주입한다.
핵심 포인트
- OTel은 새로운 로깅 API를 강제하지 않는다. 기존 로거를 그대로 사용하면서 트레이스와 상관관계만 추가한다
- 자동 계측(auto-instrumentation) 활성화 시, 로그에
trace_id와span_id가 자동 삽입된다 - 이를 통해 "이 에러 로그가 어떤 요청에서 발생했는지" 바로 추적 가능
예시
import logging
# OTel 자동 계측이 활성화되면, 기존 로그에 trace context가 자동 주입
logger = logging.getLogger(__name__)
def process_order(order_id):
logger.info(f"Processing order {order_id}")
# 출력: Processing order 12345 [trace_id=abc123 span_id=def456]
세 신호의 관계
Traces ←→ Logs : Trace ID로 연결 (이 로그가 어떤 요청?)
Traces ←→ Metrics : Exemplar로 연결 (이 지연 급등이 어떤 트레이스?)
Logs ←→ Metrics : 시간대로 상관관계 (에러 로그 급증 = 에러율 지표 상승)
Exemplar: Metric 데이터 포인트에 Trace ID를 첨부하는 기능. "이 p99 레이턴시 급등의 원인이 된 구체적인 트레이스"를 바로 찾을 수 있다.
관련 개념
- OTel Collector: 신호 데이터를 수집·처리·내보내는 파이프라인
- OTel Context Propagation: 서비스 간 트레이스 컨텍스트 전파
- OTel Instrumentation: 신호를 생성하는 계측 방법