안녕하세요! Observability(관측 가능성)의 세계를 탐험하는 개발자 여러분. OpenTelemetry(OTel)가 사실상의 표준으로 자리 잡으면서, 많은 분들이 OTel을 도입하고 계실 텐데요. 하지만 OTel SDK를 사용하면서 "대체 내부에서 어떤 부품들이 어떻게 돌아가는 거지?" 하는 궁금증을 가져본 적 없으신가요? 🤔
오늘은 마치 자동차의 엔진을 분해하듯, OpenTelemetry SDK를 구성하는 가장 중요한 4가지 핵심 컴포넌트에 대해 깊이 있게 알아보겠습니다.
자, 그럼 OTel SDK의 엔진룸으로 함께 떠나볼까요?

🕵️♀️ 환경 탐정: Resource Detector
Resource Detector는 이름 그대로 '자원 탐지기' 입니다. 애플리케이션이 시작될 때, 마치 탐정처럼 주변 환경을 샅샅이 조사해서 의미 있는 정보를 자동으로 수집하는 아주 똑똑한 친구죠.
- 핵심 역할: 내가 실행된 환경이 어디인지(AWS, GCP, Azure?), 컨테이너에서 돌고 있는지(Docker, Kubernetes?), 호스트 이름은 무엇인지 등의 환경 정보를 자동으로 감지하여 모든 텔레메트리 데이터(traces, metrics, logs)에 공통 '꼬리표'로 붙여줍니다.
- 왜 중요한가?: 이 '꼬리표' 정보 덕분에 우리는 "AWS us-east-1 리전에서 실행 중인 payment-service의 v1.2 버전에서 발생한 에러"와 같이 데이터를 훨씬 풍부한 맥락(Context) 속에서 분석할 수 있습니다. 컨테이너 ID나 Pod 이름을 알면 문제가 생긴 특정 인스턴스를 즉시 찾아낼 수 있죠.
Resource Detector가 수집하는 정보의 예시는 다음과 같습니다.
- 클라우드 정보: cloud.provider, cloud.region, cloud.account.id
- 컨테이너 정보: container.name, container.id, container.image.name
- 호스트 정보: host.name, host.arch
- OS 정보: os.type, os.version
이 모든 정보가 자동으로 추가되니, 우리가 수동으로 설정해야 하는 번거로움이 크게 줄어듭니다.
📬 컨텍스트 배달부: Propagator
Propagator는 분산 시스템(MSA)에서 '컨텍스트(Context) 전파' 라는 매우 중요한 임무를 수행합니다.
- 핵심 역할: MSA 환경에서는 하나의 요청이 여러 서비스(Service A -> Service B -> Service C)를 거쳐 처리됩니다. 이때 이 요청들이 모두 하나의 작업(Trace)에 속한다는 것을 알려주는 정보(Trace ID, Span ID 등)를 서비스 경계를 넘어 전달해주는 역할을 합니다. 마치 여러 나라를 여행하는 여행객의 '여권' 과도 같죠.
- 동작 방식:
- Inject(주입): 서비스 A가 서비스 B를 호출할 때, HTTP 헤더 같은 곳에 traceparent 와 같은 형태로 컨텍스트 정보를 주입합니다.
- Extract(추출): 서비스 B는 요청을 받으면 헤더에서 컨텍스트 정보를 추출하여 자신의 작업이 서비스 A의 작업에 이어서 계속된다는 것을 인지합니다.
- 주요 표준: W3C Trace Context(표준), B3(과거에 많이 사용) 등의 약속된 포맷을 사용합니다.
Propagator 덕분에 우리는 여러 서비스에 흩어져 있는 조각난 Span들을 하나의 아름다운 분산 트랜잭션 그래프로 볼 수 있습니다.
🎟️ 데이터 게이트키퍼: Sampler
모든 요청을 추적하면 좋겠지만, 트래픽이 많은 서비스에서는 엄청난 양의 데이터가 발생하고 이는 곧 비용 증가로 이어집니다. Sampler는 바로 이 문제를 해결하기 위해 존재합니다.
- 핵심 역할: "어떤 요청을 기록하고 어떤 요청을 버릴 것인가?" 를 결정하는 샘플링 전략을 담당합니다. 즉, 데이터 수집의 '게이트키퍼' 역할을 하는 셈이죠.
- 주요 전략:
- AlwaysOnSampler: 모든 데이터를 기록합니다. (개발 환경에 유용)
- AlwaysOffSampler: 모든 데이터를 버립니다.
- TraceIdRatioBasedSampler: 설정된 비율(예: 10%)에 따라 무작위로 데이터를 샘플링합니다. (가장 일반적인 방식)
- ParentBasedSampler: 부모 Span이 샘플링되었다면, 자식 Span도 따라서 샘플링하는 등 부모의 결정을 따릅니다.
효과적인 샘플링 전략은 비용은 줄이면서도 시스템의 상태를 파악할 수 있는 의미 있는 데이터를 확보하는 데 매우 중요합니다.
🚚 데이터 최종 배송기사: Exporter
Exporter는 SDK 파이프라인의 가장 마지막 단계를 책임지는 '데이터 배송기사' 입니다.
- 핵심 역할: 애플리케이션 내부에서 수집되고 처리된 텔레메트리 데이터를 최종 분석 시스템(Backend)으로 내보내는(Export) 역할을 합니다.
- 다양한 목적지: 어떤 분석 시스템을 사용하느냐에 따라 다양한 Exporter를 선택할 수 있습니다.
- OTLP Exporter: OpenTelemetry의 표준 프로토콜(OTLP)을 사용하여 OTel Collector나 Jaeger, Grafana Tempo 등으로 보냅니다. (가장 권장되는 방식)
- Jaeger Exporter: Jaeger 포맷으로 직접 보냅니다.
- Prometheus Exporter: Prometheus가 수집할 수 있는 포맷으로 메트릭을 노출합니다.
- Console Exporter: 데이터를 화면(콘솔)에 출력해 줍니다. (디버깅용으로 최고!)
어떤 Exporter를 사용하느냐에 따라 우리 데이터의 최종 목적지가 결정됩니다.
✨ 총정리: 데이터의 여정
자, 그럼 이 컴포넌트들이 어떻게 함께 작동하는지 데이터의 여정을 따라가며 정리해볼까요?
- (시작) 애플리케이션이 실행되면 Resource Detector가 환경 정보를 수집해 기본 '꼬리표'를 준비합니다. 🕵️♀️
- (요청 수신) 외부에서 요청이 들어오면 Propagator가 HTTP 헤더 등에서 Trace 컨텍스트를 추출합니다. 📬
- (샘플링 결정) 새로운 Trace를 시작할 때, Sampler가 이 Trace를 기록할지 말지 결정합니다. 🎟️
- (데이터 처리) 애플리케이션 코드 내에서 Span들이 생성되고, 이 Span들에는 1번에서 수집한 리소스 정보가 모두 포함됩니다.
- (데이터 전송) 처리가 완료된 데이터(Span)는 Exporter를 통해 최종 목적지(예: Jaeger)로 배송됩니다. 🚚
이제 맨 처음의 질문으로 돌아가면 답은 명확해졌습니다. 실행 환경의 속성을 '탐지'하는 것은 Resource Detector의 고유한 임무입니다. 이 네 가지 컴포넌트의 역할을 명확히 이해한다면, 여러분의 OpenTelemetry SDK 설정과 활용 능력이 한 단계 더 성장할 것이라 확신합니다!
'클라우드 > opentelemetry' 카테고리의 다른 글
| 🔍 OpenTelemetry 마스터하기: 메트릭 뷰(Metric View) 완벽 가이드 (0) | 2025.10.14 |
|---|---|
| OpenTelemetry Collector의 숨겨진 비밀 🤫: service::telemetry::metrics 완전 정복 (0) | 2025.10.14 |
| OpenTelemetry Collector, 여러 백엔드로 데이터를 똑똑하게 분산하는 방법 ⚖️ (0) | 2025.10.14 |
| OpenTelemetry Exemplar: 메트릭 스파이크의 원인을 찾아 떠나는 여행 🚀 (0) | 2025.10.14 |
| OpenTelemetry 로그와 트레이스의 완벽한 연결고리: Log Bridge API 톺아보기 🌉 (0) | 2025.10.13 |