OpenTelemetry 작동에 성공했는데, 왜 이렇게 복잡할까?
(iconsolutions.com)- 고객의 OpenTelemetry 지원 요청은 기존 Prometheus·Jaeger·OpenTracing 기반 관측 가능성이 OTel의 메트릭·로그·트레이스 요구와 완전히 같지 않다는 점을 드러냄
- 로그와 메트릭은 appender와 설정 추가로 비교적 쉽게 옮겼지만, 분산 추적은 Spring과 Akka가 같은 JVM 안에서 추적 문맥을 공유해야 해 훨씬 어려웠음
- OTel과 Lightbend Telemetry/OpenTracing은 서로 다른 Tracer API와 SpanContext 구현을 써서, 같은 트랜잭션이 별도 trace로 갈라졌음
- 해결은 OTel 문맥을 Java
Map에 inject하고 Jaeger SpanContext로 extract한 뒤, Lightbend의GlobalExtendedTracer.get().local().activateContext()로 수동 활성화하는 방식이었음 - OTel은 관측 가능성 표준화에 도움이 되지만, 기존 Akka·Jaeger 기반 계측과 섞을 때는 명시적인 문맥 연결이 필요할 수 있음
OTel이 통합하려는 관측 가능성 신호
- OpenTelemetry(OTel) 는 관측 가능성 프레임워크이자 툴킷으로, 기존에 분리되어 있던 도구 영역을 메트릭, 로그, 트레이스 세 신호로 표준화하려 함
- 기존 조합은 역할별로 나뉘어 있었음
- Prometheus: 메트릭
- Logstash와 Elasticsearch 같은 중앙 집계기: 로그
- OpenTracing: 분산 추적
- OTel은 사양뿐 아니라 핵심 구성요소도 제공함
- OpenTelemetry Protocol(OTLP): 애플리케이션이 telemetry 데이터를 보고하는 프로토콜
- OpenTelemetry Collector: 벤더 중립적으로 telemetry 데이터를 수신·처리·내보내는 구성요소
- 10개 이상 언어용 SDK: OTLP와 telemetry export 구현
- 애플리케이션은 자동 계측, API, 언어 SDK를 통해 OTel Collector로 신호를 보내고, 인프라도 Collector에 신호를 보낼 수 있음
IPF의 기존 지원과 고객 요청
- IPF는 이미 ELK Stack 연동, 모니터링, 관측 가능성 문서를 갖추고 있었고 고객도 운영 환경에서 사용해 왔음
- 프레임워크 특성상 라이브러리를 쓰는 애플리케이션이 어떤 환경에 배포될지 알 수 없어, 특정 벤더를 강제하지 않고 추상화와 재정의 가능한 기본값을 제공해야 했음
- 기본 권장사항은 로그를 Elasticsearch, LogScale 같은 집계기로 보내고, 메트릭은 사실상 표준이 된 Prometheus를 활성화·지원하는 방식이었음
- 고객들은 OTel 기반 tracing을 거의 동시에 세 건 요청했고, tracing을 OTel로 쓰는 김에 logs와 metrics도 함께 옮기는 흐름이 생김
- 로그와 메트릭은 새 appender와 설정 추가로 비교적 쉽게 처리됐지만, tracing은 별도 문제로 남음
분산 추적에서 문맥 전파가 필요한 이유
- 분산 시스템에서 하나의 트랜잭션을 추적하려면 시스템 사이에 특정 호출과 트랜잭션을 연결하는 정보를 넘겨야 하며, 이를 context propagation이라고 함
- trace는 여러 작업 단위인 span을 감싸는 부모 구조이며, span은 여러 개가 있을 수 있고 중첩될 수 있음
- 전자상거래 사이트에서 “buy now” 버튼을 누르는 흐름은 하나의 trace로 묶일 수 있음
- 프런트엔드가 백엔드와 통신하는 span
- 백엔드가 결제·배송·주문 관리 서비스와 통신하는 자식 span
- 각 다운스트림 서비스가 다시 다른 시스템과 통신하는 추가 자식 span
- OTel을 쓰는 경우 각 분산 서비스는 자신의 trace 일부를 OTel Collector로 보고하고, OTel은 단일 trace ID 아래 전체 흐름을 구성함
네 가지 문맥 전파 표준과 OpenTracing의 흔적
- OTel이 반드시 지원해야 하는 context propagation 구현은 네 가지임
- IPF의 Akka 영역은 이미 폐기 예정인 OpenTracing을 지원했고, Lightbend Telemetry의 OpenTracing 지원을 사용하고 있었음
- Lightbend Telemetry 2.20.0은 OpenTelemetry logs/events와 metrics 지원을 추가했지만, 중요한 tracing 지원은 빠져 있었음
- 이론적으로는 OTel tracing이 OpenTracing의 재브랜딩에 가깝고, Lightbend Telemetry의 OpenTracing도 네 가지 전파 방식을 지원하므로 동작할 것처럼 보였지만 실제 결과는 달랐음
Spring과 Akka 사이에서 끊긴 trace
- IPF는 Spring과 Akka를 함께 사용함
- Spring Boot와 Spring IoC: 애플리케이션 부트스트랩, 설정, 의존성 구성
- Akka: 이벤트 소싱, 스케줄링, 클러스터링, 샤딩, 통합 등
- 고객은 Spring REST controller나
@KafkaListener가 붙은 메서드로 결제 플로우를 시작할 수 있음 - OTel 이전에는 세 영역이 큰 충돌 없이 동작했음
- Metrics: Spring과 Akka가 서로 다른 Prometheus endpoint를 노출
- Logs: 두 프레임워크 모두 SLF4J와 Logback 사용
- Traces: 둘 다 OpenTracing 사용
- OTel 사용 시 metrics와 logs는 Spring과 Akka가 독립적으로 동작해 정상 전송됐지만, tracing은 JVM 내부에서 같은 trace context를 공유해야 했음
- 애플리케이션 내부에서 같은 추적 개념을 두 개의 서로 다른 API가 표현했고, 두 API가 서로 통신하지 않는 것이 실제 문제였음
- 올바른 동작은 Akka HTTP client가 기존 trace ID
123을 재사용하고 새 span ID만 만들어 같은 trace의 새 작업 단위로 표시하는 것이었지만, 실제로는 관계없는 두 trace가 생성됨
opentracing-shim과 구현체 충돌
- OTel 쪽에는 OTel
Tracer를 OpenTracingTracer처럼 보이게 하는opentracing-shim이 있음 - 하지만 Lightbend Telemetry는 커스텀 Tracer 구현을 사용했고, 이 때문에 shim과 Jaeger가 모두 실패함
- 로그에는 다음 오류가 출력됨
Expected to have an OpenTelemetry Span but got cinnamon.opentracing.TraceLocal$ContextOnlySpanExpected to have a JaegerSpanContext but got io.opentelemetry.opentracingshim.SpanContextShim
- Jaeger는 OTel shim 문맥을 받아 실패했고, OTel은 Lightbend 문맥을 받아 실패함
Java Agent와 Lightbend 내부 추적 조사
- OTel과 Lightbend Telemetry 계측은 모두 Java Agent를 사용해 특정 클래스의 특정 메서드 호출에 hook을 걸고 tracer에 활동을 보고함
- Lightbend Telemetry 계측은 오픈소스가 아니어서, 동작을 파악하려면 decompile된 tracer 코드를 조사해야 했음
- 축소 재현 예제를 만들어 Spring 쪽 OTel trace context가 Akka 쪽으로 넘어가는 어느 지점에서 끊기는지 확인함
- Jaeger가 실패하는 지점은
JaegerTracer.java의 해당 코드였음 - 호출자는 Lightbend Telemetry의 독점 계측 클래스인
OpenTracingAkkaPersistenceActorInstrumentation.class였음 - decompile된 코드에서 핵심 조건은
var5의 상태였음- OpenTracing
SpanContext인var5가 null이 아니면 새 span을 현재 활성 span의 자식으로 붙임 var5가 null이면 기존 trace와 관계없는 span이 됨var5가 Jaeger SpanContext가 아니면 Jaeger가 실패함
- OpenTracing
수동 변환으로 OTel과 OpenTracing 연결
SpanContext는this.traceLocal.currentContext()에서 가져오고 있었고,traceLocal은 Lightbend의ExtendedTracer에서 초기화되고 있었음- Lightbend 문서에는
ExtendedTracer를 전역으로 접근하는 방법이 있었음GlobalExtendedTracer.get()
GlobalExtendedTracer.get()은ExtendedTracer를 반환하고,local()은 계측 라이브러리가 쓰는 것과 같은TraceLocal을 반환함- 이
TraceLocal에는 OpenTracingSpanContext를 받는activateContext메서드가 있었음 - 해결 흐름은 네 단계였음
- OTel shim을 쓰지 않음
- 현재 OpenTelemetry Context를 Java
Map으로 inject함 - 그
Map값을 사용해 Jaeger SpanContext를 extract함 - Akka로 들어가기 전에 Lightbend
TraceLocal에 Jaeger SpanContext를 활성화함
- 사용한 OTel propagators API 작업은 inject and extract operations임
- 핵심 코드는 다음 흐름을 따름
- 빈
HashMap생성 GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator().inject(...)로 OTel context를 map에 주입new TextMapCodec(false).extract(new TextMapAdapter(otelContext))로 JaegerSpanContext 생성GlobalExtendedTracer.get().local().activateContext(openTracingContext)로 Akka 진입 전 context 활성화
- 빈
확인된 동작과 운영 권장
- 수동 연결 후 trace는 기대한 대로 이어짐
- Spring REST 호출
/submit부터 시작해 전체 흐름이 단일 trace로 연결됨 - OTel API로 계측된 부분과 OpenTracing API로 계측된 부분을 섞어 사용할 수 있었음
- HTTP 경계를 넘어 trace가 전파됨
- Spring REST 호출
- 예제에서는 두 계측 종류를 구분하려고 서로 다른 이름을 사용했지만, 실제 고객 환경에는
otel.service.name과cinnamon.application을 맞춰 외부에서 하나의 애플리케이션처럼 보이도록 권장함
복잡했던 이유와 남은 우려
- Lightbend Telemetry를 OTel API로 다시 작성하려면 현재 Jaeger API에 묶인 많은 계측을 OTel API로 포팅해야 해 큰 작업이 될 수 있음
- OTel Collector는 legacy Zipkin 형식 trace 수집을 지원하므로, Lightbend는 legacy 지원에 의존해 완전한 OTel 지원을 제공할 수 있음
- 복잡성의 직접 원인은 서로 다른 tracing 라이브러리를 사용하는 두 계측 체계를 결합하려 한 데 있음
- OTel 프로젝트는 semantic conventions 같은 표준화 시도로 관측 가능성 영역을 정리하려 하며, 처음 이해하기에는 다소 복잡하지만 유용한 FOSS 프로젝트로 평가됨
- Akka가 actor model 내부에서 thread 사이 trace context를 올바르게 전달하는지는 아직 우려가 남아 있음
- 소규모 부하 테스트에서는 기대대로 동작했음
- 관련 티켓을 Akka 쪽에 열어 둔 상태임
댓글과 토론
Hacker News 의견들
-
Otel을 배우고 포팅하는 내내 다시 Java 세계로 돌아간 느낌이었음. 코드를 한 줄씩 따라갈 때마다 EnterpriseFizzBuzz 같았고, 발견 가능성이 전혀 없었으며, 자체 용어도 뭔가에 취한 사람들이 만든 것처럼 보였음
NodeJS에서는 StatsD 대비 CPU 사용량이 약 4배였고, 결국 직접 집계를 만들어 사용량을 낮추고 태그 폭증도 줄였음. StatsD는 여러 프로세스가 같은 태그를 보고해도 괜찮지만 OTEL은 덮어써버림
피크 부하에서 CPU 하나가 60~80% 사용률로 돌았고, 뭔가 바뀌기 전에는 수직 확장도 못 했음. 코어당 프로세스 하나를 쓰는 언어에는 OTEL이 적극적으로 적대적이라 농담 같음. 그냥 Prometheus를 쓰는 게 낫고, 사실상 다른 경쟁자도 없음- OTEL은 일종의 벤더 포획 상태에 가깝다고 봄. 표준을 만들려면 여러 대기업과 허술한 스타트업의 요구를 타협해서 글루건으로 붙이는 수밖에 없었기 때문임
.NET에서 단순한 otel 설정을 해보려다 조직이 고른 벤더 문서를 몇 시간 읽고도 이해가 안 돼서, 동료가 운영하는 Discord에 들어갔음. 그쪽 비즈니스 모델 일부가 “오픈소스 제품에서 제대로 된 otel을 쓰려면 돈 내라”였는데, 곧바로 비용이 얼마든 그만한 가치가 있다고 느꼈음
OTEL 구현을 하느니 사전 경험 없이 안정적인 이벤트/발행구독 라이브러리를 하나 더 만드는 편이 낫겠음 - “다른 경쟁자도 없다”는 말에 대해, 경우에 따라 Apache SkyWalking도 볼 만함. 리소스를 많이 먹지 않고 설정과 운영이 꽤 단순하지만, UI나 문서는 덜 다듬어진 편임: https://skywalking.apache.org/
최소 구성도 실제로 꽤 작아서 웹 UI, 서버 인스턴스, 이미 알고 있는 DB 정도면 됨: https://skywalking.apache.org/docs/main/latest/en/setup/back...
모니터링 영역의 Zabbix와 비슷한 면이 있음. 둘 다 누군가를 감탄시키진 않겠지만 실용성은 충분함 - 내 결론도 같음. 그냥 Prometheus와 원하는 언어의 클라이언트 라이브러리를 쓰면 되고, OTEL 이야기보다 1000배는 단순함
- C++ 쪽에서 otel을 쓰고 있는데, 여러 애플리케이션에서 누적 메트릭을 얻으려고
process.vpid같은 비교적 낮은 카디널리티의 정수 속성을 만들었음. 앱이 살아 있는 동안 그 값이 유일하도록 전역 객체 같은 것으로 조율할 수 있음
그다음 합산하고 해당 속성을 제거하는 무언가를 두면 됨. statsd/delta에서는 신호 전송 하나를 잃으면 전체 데이터가 비틀리지만, 누적 방식에서는 정밀도만 잃음
내 용도는 스크레이프 가능한 장기 실행 프로세스가 아니라 “배치” 도구에서 오는 푸시 기반 메트릭임 - 내 경험과도 맞음. 원하는 효과를 내려면 무엇이 필요한지 이해하기가 매우 어려웠음
- OTEL은 일종의 벤더 포획 상태에 가깝다고 봄. 표준을 만들려면 여러 대기업과 허술한 스타트업의 요구를 타협해서 글루건으로 붙이는 수밖에 없었기 때문임
-
Otel이 복잡해 보이는 이유는 여러 관측성 벤더가 자기들 전용 SDK, 에이전트, API로 관측성 구현을 아주 쉽게 만들어놨기 때문임. Otel은 이 문제를 해결하려는 것이고, 만든 사람들은 훌륭하게 해내고 있다고 봄
Grafana가 OpenTelemetry를 생태계의 일급 구성요소로 받아들인 것도 칭찬할 만함
몇 년 동안 Datadog 사용을 밀어왔지만, 중견기업과 대기업 사이 규모에는 가격이 감당하기 어려워졌음. 시간이 지나 OpenTelemetry API와 SDK가 안정되면서 애플리케이션 관측성 표준으로 삼게 됨
다만 문서는 전반적으로 더 좋아질 수 있고, 온보딩 문서가 언어별로 다른 점은 이상적이지 않음
현재 팀은 NodeJS/Typescript 스택이고, OpenTelemetry를 빠르게 시작할 수 있게 패키지 묶음과 예제 Grafana 스택을 만들었음: https://github.com/zonneplan/open-telemetry-js- 모두가 아주 쉽게 만들어서 생긴 문제를, 이 제품은 복잡하게 만들어서 해결한다는 건가? ;P
- Datadog보다는 그냥 좋은 메트릭 수집을 선호함. 반면 OTEL이 내가 선호하는 방식보다 가치가 있다는 건 이론적으로는 이해함
모든 APM 벤더에서 가장 큰 문제는 마법 같은 에이전트로 커널 훅을 갖게 되는 순간, 개발자가 설명할 수 없는 온갖 일이 생긴다는 점임
예전에 다른 회사에서 Dynatrace를 도입했는데, 다행히 앱에는 이미 충분한 내장 메트릭이 있어서 리드 SRE가 계측의 “모범”이라고 볼 정도였음. 그런데 앱 호스트에 Dynatrace 에이전트를 설치하자마자 노드 재시작이 필요한 여러 하이젠버그가 생기고 성능 저하도 직접 측정됐음
아이러니하게도 메트릭 덕분에 고통을 피했지만, 고칠 방법은 아무도 몰랐음. 가장 심했던 건 MSSQL 업데이트 시 장애조치가 ADO.NET 연결 풀을 이상하게 오염시키는 경우였음
-
필요한 만큼만 복잡해지는 구조임. 마법 같은 기능을 피하고, 맥락상 가장 가치 있으면서 이해하기 쉬운 부분집합만 써도 됨
우리 팀에서는 매우 단순함. 트레이스만 보내는 라이브러리를 쓰고, 트레이스가 애플리케이션 관찰에 가장 큰 가치를 주며 다른 유형의 데이터도 담을 수 있음. 기본적으로 문자열·실수 대신 해시맵을 쓰는 셈임
자동 계측 대신 수동 계측을 쓰며, 무엇을 관찰할지 의도적으로 정하고 어떤 코드가 스팬을 내보내는지 잘 이해함. 코드 구성과 맞는 이름 규칙도 있음
백엔드는 저렴한 서드파티 서비스와 로컬 개발용 all-in-one Jaeger 설치를 함께 씀. 후자는 실행 파일 하나나 Docker 컨테이너 하나만 돌리면 되고 스팬을 디스크에 저장하지 않음. 주로 팀원들이 서드파티 서비스를 넘치게 만들지 않도록 안심시키는 용도임
인프라 모니터링은 기존 설정이 있고, 우리 경우에는 모든 인프라 로그와 메트릭을 수집하는 데 큰 가치를 못 느낌. OTEL 메트릭과 로그는 아직 초기 단계라고 보지만 벤더들은 그렇게 말하지 않음- 원하는 만큼 복잡해질 수는 있지만, 내가 원하는 만큼 쉽지는 않음. 최소 난이도가 꽤 높음
아직 스크레이프할 수 없는 인프라 일부에서 단순한 일회성 메트릭을 보낼 엔드포인트를 찾고 있음 - 수동 계측이 더 단순하다고 느끼진 못했음. 결과를 보여주기 훨씬 전부터 학습 곡선이 시작되는 대신, 이 루브 골드버그 기계가 만드는 성능 비용을 더 명확히 이해하게 되는 거래에 가까움
Otel은 새 프로젝트라면 괜찮을 수 있지만, 이미 텔레메트리가 있는 운영 서비스에서 켜는 건 달리는 차량의 타이어를 교체하는 느낌이었음 - 그 저렴한 서드파티 서비스가 무엇인지 공유해줄 수 있음?
- 매우 합리적인 조언임. 대부분 이미 메트릭과 로그용 무언가를 갖고 있을 테고, 바꿀 투자 대비 효과가 없다면 굳이 할 이유가 없음
- “마법을 피하고 부분집합만 쓰면 된다”는 건 사용하는 모든 라이브러리도 그 부분집합만 쓸 때만 가능함. 내 경험상 압도적으로 그렇지 않았고, 글도 왜 그런지에 대한 구체적인 예를 잘 보여줌
otel만 쓰고 비-otel 프레임워크가 없는 그린필드 프로젝트라면 좋을 수 있다고 믿음. 하지만 나는 아직 그런 세계에 살고 있지 않음
- 원하는 만큼 복잡해질 수는 있지만, 내가 원하는 만큼 쉽지는 않음. 최소 난이도가 꽤 높음
-
가장 큰 문제 중 하나는 로컬 개발 경험이었음. 로컬에서 로그, 트레이스, 메트릭을 지원하고 싶었지만 그걸 위해 Docker 이미지를 잔뜩 띄우고 싶지는 않았음. 배포 전에 메트릭, 트레이스, 배기지, 액티비티 스팬이 어떻게 보이는지 로그로 확인하고 싶었음
최근 .NET 팀이 .NET Aspire를 내놨는데 아주 좋음. 로컬 개발 스택에서 모든 걸 한곳에 시각화하기 쉽고, 코드로 된 오케스트레이터처럼 동작함
k8s에 배포할 때는 OTEL 엔드포인트를 DataDog Agent로 향하게 하면 모든 게 그냥 동작함. DataDog의 커스텀 트레이스 라이브러리와 SDK는 피하고 OTEL만 씀
이제 개발 경험이 꽤 좋아졌음
https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals...
https://docs.datadoghq.com/opentelemetry/#overview- 그 용도에는 이 프로젝트가 정말 좋음: https://github.com/grafana/docker-otel-lgtm
- https://github.com/CtrlSpice/otel-desktop-viewer도 있음
- 그냥 https://github.com/openobserve/openobserve를 쓰면 됨
처음 로컬 개발 머신에 설정하는 데 5분이면 되고, 이후에는 별도 터미널 탭에서/path/to/openobserve만 실행하면 끝임. 단일 정적 링크 바이너리라는 거대한 복잡성을 피하고 싶다면 로컬·원격 실행용 Docker 이미지도 제공함 :P
예쁜 그래프가 있는 올인원 OpenTelemetry 백엔드이고, 내 프로젝트들에서는 아직 감지 가능한 방식으로 실패한 적이 없음 - .NET Aspire에는 설득되지 않음. 로컬 개발에서 여러 서비스 프로젝트의 서비스 디스커버리와 오케스트레이션이라는 작은 문제를 풀지만, 그걸 애플리케이션 레벨 관심사로 만들어 해결함
Aspire를 쓰면 앱 레벨에 불필요한 복잡성을 추가하고 좁은 생태계에 묶이게 됨. 로컬 개발에는 docker compose 같은 검증된 대안이 많고, Aspire가 docker compose와 환경 변수보다 딱히 훨씬 쉽지도 않음 - 모든 것이 들어 있는 공식 all-in-one Docker 이미지가 있음
-
Python에서 otel을 한다면 Logfire의 클라이언트를 쓰는 게 좋음. Logfire 서비스를 쓰지 않더라도 마찬가지임
오픈소스이고, 어떤 otel 호환 엔드포인트로도 보낼 수 있음. 게다가 pydantic 팀이 만든 클라이언트가 공식 otel 라이브러리보다 10배는 낫고 단순함
Samuel Colvin이 어떻게 여기까지 왔는지 설명하는 흥미로운 인터뷰도 있음: https://www.bitecode.dev/p/samuel-colvin-on-logfire-mixing-p... -
그래서 OpenTelemetry 도입을 명령 한 줄만큼 쉽게 만드는 데 초점을 둔 오픈소스 프로젝트를 시작했음: https://github.com/odigos-io/odigos
-
요즘은 많은 웹 프레임워크가 대부분의 계측을 대신 해줌. 예를 들어 opentelemetry-js를 쓰고 https://signoz.io 같은 것을 직접 호스팅하면 한 시간도 안 돼 띄울 수 있고, 커스텀 코드를 쓰지 않아도 많은 데이터를 얻을 수 있음
- SigNoz 저장소는 여기 있음: https://github.com/signoz/signoz
- 다중 스레드 비동기 런타임에서 컨텍스트 전파는 간단하지 않음. 방법은 여러 가지지만, 바이트코드를 계측하는 JVM 에이전트가 인기 있는 이유는 투명하게 동작하기 때문임
-
OpenTelemetry는 트레이스에서 성장했지만, 메트릭과 로그는 전문 솔루션에 맡기는 편이 훨씬 나음
“새는 추상화” 또는 “새는 프레임워크” 문제처럼 느껴짐. 모든 걸 한 우산 아래 넣고 싶다면 SQL 데이터베이스도 이 모든 걸 동시에 할 수 있음. 그렇다고 그래야 한다는 뜻은 아님- Cramer는 OTel에서 트레이스를 빼고 싶어 함. OpenTracing 창시자 중 한 명이라는 점에서 아이러니함
https://cra.mr/the-problem-with-otel/ - 메트릭과 로깅에 트레이스 안의 위치를 부여하는 건 정말 유용하다고 봄
그래도 OTel을 다룰 때마다 여전히 싫음
- Cramer는 OTel에서 트레이스를 빼고 싶어 함. OpenTracing 창시자 중 한 명이라는 점에서 아이러니함
-
끝까지 읽어보면 고통은 대부분 스스로 만든 것임을 알 수 있음. Python의 표준 스택(mysql, flask, redis, requests 등)에서는 아주 쉬웠음. 서비스 상단에 import 몇 개만 넣으면 자동으로 연결되어 별다른 소란 없이 모든 걸 추적함
- 맞지만, 스택의 모든 것이 자동 계측을 지원할 때만 그렇음. 예를 들어
aiohttp는 최신 버전이 3.11.X인데, 자동 계측은3.X를 지원한다고 되어 있지만 [0] 실제 결과는 사용하는aiohttp가 얼마나 최신인지와 자동 계측 쪽 상태에 따라 달라짐
전부 잘 맞아떨어지면 마법처럼 동작하지만, 그 바늘구멍은 꽤 좁음
[0]: https://github.com/open-telemetry/opentelemetry-python-contr... - 최근 아주 단순한 Flask 앱에 이걸 붙여야 했음. 사내 인트라넷 안에서만 돌아가야 해서, 단일 서버에서 docker compose로 otel-collector-contrib, jaeger-all-in-one, prometheus를 돌리고 있음
트레이스는 동작하고 spanmetrics exporter도 설정했으며, prometheus에 직접 질의하면 spanmetrics가 보임. 하지만 무슨 짓을 해도 jaeger의 “monitor” 탭에는 나타나지 않음
여기에 3일을 쓰고 나니 상사가 “그냥 수동 계측해서 전부 SQL 서버로 보내고 Grafana 대시보드를 만들면 어떠냐”고 했는데, 그것도 하고 싶지 않음
가장 단순한 사용 사례인데도 안 됨. Grafana를 더 얹어야 하는 건가? - gunicorn 같은 것 뒤에서 서버를 돌리기 전까지만 그렇음. 그 순간 모든 자동 import가 멈추고 전부 직접 해야 함
- 맞지만, 스택의 모든 것이 자동 계측을 지원할 때만 그렇음. 예를 들어
-
복잡한 이유는 구현하는 엔지니어가 아니라 Otel 호환 소프트웨어를 파는 회사들을 위해 설계됐기 때문임
- 그건 잘 모르겠음. 벤더들은 자기 전용 코드, 에이전트, 백엔드에 만족했을 것 같음. 잠금 효과 덕분에 새 코드를 전부 써야 하므로 전환 비용이 매우 높아지기 때문임
- 기여자들에게서 본 모습은 그렇지 않았음
오히려 백엔드들이 도입에 꽤 느렸다고 봄 - 까다롭게 들리겠지만, 예전에는 ‘implement’가 전자의 활동, 즉 명세에 맞춰 소프트웨어를 앉아서 작성하는 일을 가리켰음. 후자처럼 기존 소프트웨어를 가져다 서버에 배포하는 뜻은 아니었음
의미는 변하는 것이니 괜찮지만, 이제는 명세에 맞춰 소프트웨어를 작성하는 일을 가리킬 단어가 사라지고 “기존 소프트웨어를 서버에 배포하는 일”만 남은 게 재미있음