상위: OpenTelemetry
요약
계측(Instrumentation)은 애플리케이션 코드에서 텔레메트리 데이터를 생성하는 과정이다. OpenTelemetry는 자동 계측(코드 변경 없이), 수동 계측(API로 직접 Span 생성), 프로그래매틱 계측(코드에서 SDK 설정) 세 가지 방식을 제공한다.
자동 계측 (Zero-Code)
코드를 수정하지 않고, 에이전트가 런타임에 라이브러리를 모니키패칭(monkey-patching)하여 텔레메트리를 수집한다.
Python 예시
# 1. 패키지 설치
pip install opentelemetry-distro opentelemetry-exporter-otlp
# 2. 사용 중인 라이브러리에 맞는 계측 패키지 자동 설치
opentelemetry-bootstrap -a install
# Flask → opentelemetry-instrumentation-flask 자동 설치
# requests → opentelemetry-instrumentation-requests 자동 설치
# 3. 에이전트로 애플리케이션 실행
OTEL_SERVICE_NAME=order-service \
OTEL_TRACES_EXPORTER=otlp \
OTEL_METRICS_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 \
opentelemetry-instrument python app.py
이것만으로 Flask HTTP 요청, DB 쿼리, HTTP 클라이언트 호출 등에 자동으로 Span이 생성된다.
자동 계측이 커버하는 것
- HTTP 서버/클라이언트 (Flask, Django, FastAPI, requests, httpx)
- DB 클라이언트 (SQLAlchemy, psycopg2, pymongo, redis)
- 메시징 (kafka-python, celery)
- gRPC, GraphQL 등
한계
- 비즈니스 로직 수준의 세밀한 추적은 불가
- 커스텀 속성(주문 ID, 사용자 ID 등) 추가 불가
- 지원되지 않는 라이브러리는 추적 안 됨
수동 계측 (Manual)
OTel API를 사용하여 직접 Span을 생성하고, 속성/이벤트를 추가한다.
from opentelemetry import trace
tracer = trace.get_tracer("order-service")
def process_order(order):
with tracer.start_as_current_span("process_order") as span:
# 커스텀 속성 추가
span.set_attribute("order.id", order.id)
span.set_attribute("order.amount", order.total)
span.set_attribute("customer.tier", order.customer.tier)
try:
validate_order(order)
charge_payment(order)
with tracer.start_as_current_span("save_order") as child:
child.add_event("saving_to_db", {"table": "orders"})
db.save(order)
except PaymentError as e:
span.set_status(trace.StatusCode.ERROR, str(e))
span.record_exception(e)
raise
수동 계측의 장점
- 비즈니스 컨텍스트 추가 (주문 ID, 결제 금액 등)
- 세밀한 성능 측정 (특정 함수, 알고리즘 단위)
- 커스텀 이벤트 기록
- 에러 상세 정보 첨부
프로그래매틱 계측 (Programmatic)
코드에서 SDK를 직접 초기화한다. 자동 계측의 환경변수 설정을 코드로 옮긴 것.
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
# Resource 정의 (서비스 정보)
resource = Resource.create({
"service.name": "order-service",
"service.version": "1.2.0",
"deployment.environment": "production",
})
# TracerProvider 초기화
provider = TracerProvider(resource=resource)
provider.add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint="http://collector:4317"))
)
trace.set_tracer_provider(provider)
어떤 방식을 선택?
| 자동 | 수동 | 프로그래매틱 | |
|---|---|---|---|
| 코드 변경 | 없음 | 많음 | SDK 초기화만 |
| 세밀함 | 라이브러리 수준 | 함수 수준 | SDK 설정 수준 |
| 시작 비용 | 매우 낮음 | 높음 | 중간 |
| 권장 시나리오 | 빠른 시작, PoC | 비즈니스 로직 추적 | 세밀한 SDK 제어 |
실전 권장: 자동 계측으로 시작하고, 필요한 부분만 수동 계측을 추가한다. 두 방식은 함께 사용할 수 있다.
관련 개념
- OTel Signals: 계측으로 생성하는 세 가지 텔레메트리 신호
- OTel Collector: 계측된 데이터를 받아 처리하는 파이프라인
- OTel Context Propagation: 서비스 간 트레이스 컨텍스트 전파