4P by neo 2달전 | ★ favorite | 댓글 1개
  • OpenTelemetry (OTel) 은 관측 가능성 프레임워크 및 도구 모음
  • 기존 도구로는 Prometheus(메트릭), Logstash(로그), OpenTracing(분산 추적)이 있음
  • OTel은 메트릭, 로그, 추적이라는 세 가지 신호를 표준화하고, OpenTelemetry Protocol (OTLP), OpenTelemetry Collector, 다양한 언어 SDK를 제공함
    • 오픈 소스, 벤더 독립, 언어 독립, 분산, 제로 코드 등 모든 유행어를 충족함

OTel의 문제점

  • 로그와 메트릭스는 기존 도구와 유사해 손쉽게 통합 가능. 설정 추가만으로도 OTel로 전환 가능
  • 추적 구현의 어려움
    • Context Propagation: 분산 시스템 간 요청 정보를 전달하기 위해 필요
      • 요청 단위를 TraceSpan으로 나눔
      • 예: "구매하기" 버튼 클릭 → Frontend → Backend → Payment/Shipping 서비스 간의 관계를 Span으로 표현
    • OTel의 지원 방식:
      • 다양한 Context Propagation 표준 제공 (예: b3, W3C Trace Context)
    • OTel은 여러 표준을 지원해야 함
      • 기존 OpenTracing에서 OTel로 전환 시 예상치 못한 충돌 발생
      • Lightbend Telemetry는 OpenTelemetry 로그와 메트릭을 지원하지만, 추적은 지원하지 않음.

API 간 충돌 문제

Spring과 Akka의 통합 문제

  • Spring: 애플리케이션 부트스트래핑 및 구성 관리
  • Akka: 이벤트 소싱, 스케줄링, 클러스터링 등에 사용
  • 문제:
    • OTel 사용 시, Spring과 Akka의 추적 API가 상호작용하지 않음
    • 동일한 Trace ID를 공유하지 못함 → 잘못된 추적 결과

해결책: OpenTracing Shim

  • OTel Tracer를 OpenTracing Tracer로 변환하는 도구
  • 문제:
    • Akka의 Lightbend Telemetry가 OpenTracing 구현을 맞추지 못함
    • Jaeger와 OTel이 서로 다른 SpanContext를 요구하여 충돌 발생

해결 과정

OTel과 OpenTracing의 수동 통합

  • OTel Context를 수동으로 Jaeger SpanContext로 변환:
    • OTel 컨텍스트를 Java Map에 삽입
    • Jaeger SpanContext에 해당 맵을 추출하여 수동으로 설정
  • 코드 예:
    var otelContext = new HashMap<>();  
    GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator()  
        .inject(Context.current(), otelContext, (carrier, key, value) -> carrier.put(key, value));  
    var openTracingContext = new TextMapCodec(false).extract(new TextMapAdapter(otelContext));  
    GlobalExtendedTracer.get().local().activateContext(openTracingContext);  
    
  • 결과:
    • Spring과 Akka 간의 추적 데이터 통합 성공
    • HTTP 경계 간 Trace가 제대로 연결됨

결론

복잡함의 원인

  • 두 가지 다른 추적 라이브러리의 통합 시도
  • OpenTelemetry가 제공하는 표준은 유용하나, 기존 도구와의 충돌 가능성 존재

OpenTelemetry의 가치

  • OpenTelemetry는 관찰 가능성의 표준화를 위해 중요한 역할을 수행
  • 복잡하지만 강력한 오픈 소스 프로젝트

향후 과제

  • Akka의 Trace Context가 스레드 간 올바르게 전달되는지 확인 필요
  • 프로젝트 개선을 위해 추가적인 테스트 및 피드백 필수
Hacker News 의견
  • Otel을 배우고 포팅하는 동안 Java 세계로 돌아간 느낌이었음. 코드 탐색 시 EnterpriseFizzBuzz 같은 느낌이었고, 발견 가능성이 전혀 없었음. NodeJS에서는 StatsD보다 약 4배의 CPU 사용량이 있었고, 자체 집계를 통해 이를 줄였음. OTEL은 코어당 하나의 프로세스를 사용하는 언어에 적대적임. Prometheus를 사용하는 것이 좋음.

  • Otel은 다양한 관측 가능성 공급업체가 제공하는 SDK, 에이전트, API로 인해 복잡하게 느껴질 수 있음. OpenTelemetry를 표준으로 사용하게 되었고, Grafana가 OpenTelemetry를 채택한 것에 찬사를 보냄. Datadog의 가격이 중간 규모 회사와 대기업 사이에서 통제 불가능해졌음. 문서화가 더 나아질 수 있으며, 프로그래밍 언어별로 온보딩 문서가 다름. NodeJS/Typescript 스택에서 OpenTelemetry를 빠르게 시작할 수 있는 패키지와 예제 Grafana 스택을 만들었음.

  • 로컬 개발에서 로그, 추적, 메트릭 지원을 원했지만 여러 Docker 이미지를 실행하고 싶지 않았음. .NET 팀이 .NET Aspire를 출시했으며, 로컬 개발 스택에서 모든 것을 쉽게 시각화할 수 있음. k8s에 배포할 때 OTEL 엔드포인트를 DataDog 에이전트에 연결하면 모든 것이 작동함. DataDog의 맞춤형 추적 라이브러리와 SDK를 피하고 OTEL을 사용함.

  • OpenTelemetry는 필요에 따라 복잡할 수 있음. 우리 팀은 간단하게 사용하며, 수동 계측을 사용하여 관찰할 대상을 신중하게 선택함. 두 가지 백엔드를 사용하며, 하나는 저렴한 서드파티 서비스, 다른 하나는 Jaeger 설치로 로컬 개발을 위한 것임.

  • Python에서 Otel을 사용할 때 Logfire의 클라이언트를 사용하는 것이 좋음. Pydantic 팀이 만든 클라이언트가 공식 Otel 라이브러리보다 훨씬 좋고 간단함.

  • 많은 웹 프레임워크가 대부분의 계측을 자동으로 처리함. opentelemetry-js를 사용하고 Signoz 같은 것을 자체 호스팅하면 한 시간 이내에 많은 데이터를 얻을 수 있음.

  • OpenTelemetry 채택을 쉽게 하기 위해 단일 명령어로 실행할 수 있는 오픈 소스 프로젝트를 시작했음.

  • Python에서 표준 스택을 사용하면 몇 가지 임포트만으로 모든 것을 자동으로 추적할 수 있음. Otel은 Otel 호환 소프트웨어를 판매하는 회사들을 위해 설계되었기 때문에 복잡함.

  • OpenTelemetry는 추적에서 시작되었지만, 메트릭과 로그는 전문 솔루션에 맡기는 것이 더 나음. 모든 것을 하나의 우산 아래에 두려는 시도는 "누수 추상화" 문제처럼 느껴짐. SQL 데이터베이스도 모든 것을 동시에 할 수 있지만, 그렇다고 해서 그래야 하는 것은 아님.