본문 바로가기
Infra2026년 4월 17일6분 읽기

OpenTelemetry 완전 가이드 — Trace·Metric·Log 통합 설정과 Collector 아키텍처

YS
김영삼
조회 292

핵심 요약

OTel은 관측성 데이터 수집의 벤더 중립 표준이다. 앱은 OTel SDK만 심고, 백엔드(Datadog·Jaeger·Prometheus·Loki 등)는 Collector가 선택해 라우팅한다.

3대 시그널

  • Trace: 요청 경로 추적 (서비스 간 span)
  • Metric: 집계 수치 (카운터, 게이지, 히스토그램)
  • Log: 이벤트 텍스트

셋을 trace_id로 상호 연결하는 것이 핵심 가치.

아키텍처

[앱 + OTel SDK] ──OTLP──> [OTel Collector] ──┬─> Jaeger/Tempo
                                              ├─> Prometheus
                                              ├─> Loki
                                              └─> 벤더 SaaS

Collector가 있으면 백엔드 교체가 앱 코드 수정 없이 가능.

Node.js 자동 계측

// instrumentation.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  serviceName: 'api',
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
NODE_OPTIONS="--require ./instrumentation.js" node app.js

커스텀 span

import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('orders');

async function placeOrder(req) {
  return tracer.startActiveSpan('placeOrder', async (span) => {
    try {
      span.setAttribute('user.id', req.userId);
      const r = await db.insert(req);
      span.setStatus({ code: 1 });
      return r;
    } catch (e) {
      span.recordException(e);
      span.setStatus({ code: 2, message: e.message });
      throw e;
    } finally {
      span.end();
    }
  });
}

Collector 설정

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc: { endpoint: 0.0.0.0:4317 }
      http: { endpoint: 0.0.0.0:4318 }
processors:
  batch: {}
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: errors
        type: status_code
        status_code: { status_codes: [ERROR] }
      - name: slow
        type: latency
        latency: { threshold_ms: 500 }
      - name: probabilistic
        type: probabilistic
        probabilistic: { sampling_percentage: 5 }
exporters:
  otlphttp/tempo: { endpoint: http://tempo:4318 }
  prometheus: { endpoint: 0.0.0.0:9464 }
service:
  pipelines:
    traces:  { receivers: [otlp], processors: [tail_sampling, batch], exporters: [otlphttp/tempo] }
    metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }

Log 연계

앱 로거(winston, pino)에 trace_id를 자동 주입하면 Grafana에서 Trace → Log 드릴다운이 가능해진다.

비용 최적화

  • Tail sampling: 에러·지연 span 위주로 남기고 나머지 5% 유지
  • Metric cardinality: 사용자ID를 라벨에 넣으면 폭발. 집계 키로만 사용
  • Log volume: 구조화 + level 별 분리 저장

자주 묻는 질문

Prometheus 직접 연동 vs OTel?

Prometheus 단독은 Pull 모델. 다중 시그널·tail sampling·멀티 백엔드가 필요하면 OTel 경유가 표준.

Datadog Agent와 공존 가능?

Agent에 OTLP 수신을 켜면 OTel SDK로 통일 가능. 점진 이관 전략으로 권장.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록