OpenTelemetry의 유지관리 인력 집중, 안정성 요구사항, 기능 제공 지연 문제를 데이터로 살펴보고 가능한 해결책을 제안합니다.
수년 동안 팀을 벤더 전용 SDK에서 OpenTelemetry로 옮기려 할 때마다 가장 꾸준히 듣는 불만 중 하나는 대략 이런 말입니다. “왜 이건 아직 끝나지 않은 것처럼 보이나요?”
관측성을 위한 벤더 SDK는 좋게 말하면 바보도 쓸 수 있습니다. 그걸 설치하면 대시보드가 그냥 데이터를 불러오고, 그 모든 조각이 어떻게 맞물리는지는 다른 누군가가 걱정하며, 여러분은 삶을 계속 살아가면 됩니다. 반대로 OpenTelemetry는 문을 열자마자 수많은 “experimental” 도장과 특정 작업 하나를 수행하는 대략 여섯 가지 서로 다른 방법으로 여러분을 맞이합니다.
OpenTelemetry를 변호하자면, 이것은 애초에 그들이 프로젝트로서 추구하던 바가 아니었습니다. 데이터로 무엇을 하든 진정으로 신경 쓰지 않는 진정한 벤더 비종속 시스템을 만들려 했다는 점에서, 그들이 늘 원칙을 지킨 것을 존중합니다. OTel에서 특정 벤더가 강하게 선호된다는 인상을 받은 적은 한 번도 없습니다. 관측성 생태계가 얼마나 수익성이 높고 논쟁적인지를 생각하면 이는 대단한 성과입니다. 또한 이 프로젝트의 유지관리자들이 대체로 바로 그 회사들에 고용되어 있다는 점을 고려하면 더욱 그렇습니다.
시간이 흐르면서 저는 불안해지기 시작했습니다. semantic-conventions 저장소의 논의는 계속되고 또 계속되고 또 계속됩니다. 언어마다 상황은 극적으로 달랐습니다. Golang과 Dotnet은 일급 시민이었지만, 다른 언어들은 몇 년씩 뒤처졌습니다.
시간, 예산 또는 감정적 여유가 없는 작은 팀에 OpenTelemetry를 추천하기 전에는 많은 탐색 질문을 하기 시작했습니다. 자동 계측은 정말 마법 같았지만, “자동 계측이 작동한다”와 “이제 뭔가를 수동으로 계측해야 한다” 사이의 절벽은, 사람들을 그 아래로 밀기 전에 경고할 의무가 있을 만큼 가팔랐습니다.
이 서사는 한동안 관측성 영역에서 이어져 왔습니다. “OTel 세계에 뭔가 문제가 있다”는 막연한 감각 말입니다. 하지만 여기서 실제 데이터를 만들어 봅시다. 실제 문제가 있는 걸까요, 아니면 커뮤니티가 느끼는 느린 진전은 환상일까요? 문제는 유지관리자가 부족해서일까요, 범위가 너무 커서일까요, 아니면 그 중간 어딘가일까요?
처음 제 추측은 “아, 이건 전형적인 오픈 소스 프로젝트가 감당할 수 있는 것보다 더 크게 한 경우군”이었습니다. 유지관리자도 부족하고 예산도 부족한 경우요. 실제로 그런 부분도 있지만, 다른 무언가도 일어나고 있습니다.
OpenTelemetry 내부에서 실제로 일어나고 있는 문제는 세 방향 충돌입니다. 바이너리 안정성 관문이 있고, 이것이 실제 유지관리자의 매우 얇은 인력층과 결합되며, 거기에 그들이 지원하려는 언어와 프레임워크의 _막대한 범위_가 더해집니다. 기능을 experimental이 아니라고 표시한 뒤에는 안정적으로 출시된 것을 결코 바꿀 수 없기에, 기능이 만들 수 있는 잠재적 문제를 논쟁할 유인이 생기는 완벽한 폭풍이 만들어집니다.
현재 OpenTelemetry는 어지러울 정도로 많은 언어와 프레임워크를 지원하려 합니다.
OpenTelemetry는 거대한 프로젝트입니다. 수십 개 언어, 수백 개 라이브러리, 그리고 셀 수 없이 많은 백엔드에 걸쳐 있습니다. 제정신을 유지하기 위해 프로젝트는 작업을 두 가지 범주로 나눕니다.
로그, 메트릭, 트레이스를 전송할 수 있도록 대상과 함께 실행되는 otel-collector가 있습니다. 그것도 대략 같은 패턴을 따릅니다. 하지만 언어에서 core와 contrib를 이야기할 때는 이것을 뜻합니다.
opentelemetry-python (core)API, SDK, OTLP 익스포터, 컨텍스트 전파, 리소스 감지 기본 요소
opentelemetry-python-contribFlask, Django, requests, psycopg2, Redis, Kafka, boto3 등의 계측 라이브러리
망가지는 것은 contrib에 들어가고, 망가지지 않는 것은 core에 들어갑니다.
이것이 충돌을 일으키는 이유가 있습니다. 대부분의 프로젝트에서 contrib는 엄청난 과잉입니다. 일반적으로 필요한 하나를 추가하려고 익스포터 300개를 원하지는 않을 것입니다. 언어 측에서는 큰 문제가 아닙니다. pip install opentelemetry-instrumentation-flask를 실행하면 flask에 필요한 것을 얻습니다. 그러나 collector 측에서는 자체 collector를 만들기 위해 OpenTelemetry Collector Builder를 사용해야 합니다(아니면 대충 흐름에 몸을 맡기고 잘 풀리기를 바랄 수 있습니다). 이것이 존재한다는 점은 멋지지만, 팀에 맡기라고 요구하기에는 범위가 큽니다.
그래서 저는 OTel에 새 기능을 추가하는 워크플로를 아마도 파악했다고 생각합니다. 여기서 제 숙제를 확인할 수 있습니다.
제가 정말 명확히 알지 못하는 것들
OpenTelemetry는 CNCF 프로젝트이므로, 다른 CNCF 프로젝트와 비교하는 것이 가장 타당하다고 생각했습니다. 비교 기준은 Envoy와 Prometheus입니다. 오픈 소스 프로젝트의 “건강성”을 측정하기 위해 전에 사용했던 임시방편 Python 스크립트를 썼는데, 아마 최선은 아닐 것입니다. 하지만 사람들이 검토하고, 제가 생성한 것에서 문제를 찾을 수 있도록(그럴 가능성이 높습니다) 차트 없는 원시 데이터 링크를 포함하겠습니다.
Envoy의 24개월 활동을 살펴보면 꽤 건강한 프로젝트임을 알 수 있습니다. 작성자, 병합자, 이슈 종료자의 분포가 좋습니다. phlax는 분명 프로젝트에 매우 중요하지만, 전반적으로 필요할 때 투입될 수 있는 탄탄한 인력층이 있습니다. 알려진 모든 봇 트래픽을 걸러내려 했습니다.
이를 OpenTelemetry 언어 중 하나와 비교해 봅시다. 제가 가장 전문적으로 경험한 것은 Golang과 Python이지만, 커뮤니티의 많은 사람에게 Ruby와 PHP 쪽이 상당히 어려움을 겪는다는 이야기를 듣습니다. 다음은 같은 기간의 PHP입니다.
매우 분명하게 두 사람에게 너무 많은 것이 집중되어 있음을 볼 수 있습니다. 이것은 건강한 오픈 소스 프로젝트가 아니며, OTel이 포괄해야 할 범위를 감당할 사람이 분명히 충분하지 않습니다. Ruby도 같은 이야기입니다.
비교하면 제 의견으로 가장 “강력한” OpenTelemetry SDK인 Golang과 Dotnet은(Python도 결코 만만하지 않지만) 더 건강해 보입니다.
Golang

그러므로 첫 번째 문제는 아마도 가장 놀랍지 않을 것입니다. 너무 적은 유지관리자에게 너무 많이 집중되어 있습니다. 작성자가 병합자이면서 이슈 종료자여서도 안 됩니다. 이상적으로는 이 업무가 더 균등하게 분배되어야 합니다.
참고로 유지관리자들이 논의를 공개적으로 유지하려 잘했다고 생각합니다. 여러 유지관리자 그룹의 공개 회의 기록을 찾아 읽고 무슨 일이 일어나는지 보는 것은 매우 쉬웠습니다. 이 유지관리자들이 사람들이 참여하는 것을 막으려 한다는 인상은 받지 못했습니다. 오히려 안정성에 대한 기대가 프로젝트를 어느 정도 제자리에 얼려 버린 듯합니다.
문제는 더 고전적인 “누군가는 유지관리자에게 돈을 지불해야 한다”는 경우입니다. 이 프로젝트는 누군가가 취미로 현실적으로 수행하기에는 너무 복잡합니다. 이처럼 긴 안정성 계약을 맺는 프로젝트가 도움을 기대하며 취미 활동가 커뮤니티에 의존할 수는 없다고 생각합니다. 저는 무료로 이 규모와 중요도의 프로젝트에서 요구받을 일을 하기 위해 회의에 참여하고 활동할 수 없습니다. 하지만 이 중요한 일을 하는 사람들에게는 소속 조직이 기대를 부과한다는 뜻이기도 합니다.
| 저장소 | 24개월 병합 PR | 고유 병합자 | 최상위 1명 병합자 비율 | 최상위 병합자 역할 |
|---|---|---|---|---|
opentelemetry-cpp | 544 | 4 | 86.1% | 단일 인간 (marcalff) |
opentelemetry-kotlin | 281 | 2 | 79.7% | 단일 인간 (fractalwrench) |
opentelemetry-browser | 102 | 4 | 79.5% | 단일 인간 |
opentelemetry-ruby | 213 | 5 | 78.7% | 단일 인간 |
opentelemetry-js | 829 | 14 | 64.9% | 고도로 집중됨 |
opentelemetry-python | 486 | 4 | 61.4% | 단일 인간 (xrmx) |
opentelemetry-php | 181 | 2 | 53.0% | 병합자 총 2명 |
semantic-conventions | 911 | 9 | 49.7% | 단일 인간 (lmolkova) |
opentelemetry-go | 686 | 5 | 36.9% | 분산된 인력층 |
opentelemetry-dotnet | 657 | 6 | 31.5% | 분산된 인력층 |
prometheus | 1,849 | 31 | 14.4% | 폭넓은 인력층 |
envoy | 5,432 | 28 | 35.8% | 폭넓은 인력층 |
그러므로 이 SDK들에는 유지관리자가 너무 적습니다. 하지만 그것만으로 새 기능이 스택을 통과하는 데 왜 그렇게 오래 걸리는 듯한지는 완전히 설명되지 않습니다. 제 추측은 새 아이디어 제출과 아이디어의 공식화 사이 과정 어딘가에 백만 년이 걸리는 긴 논의가 있다는 것이었습니다.
서로 다른 프레임워크와 언어에 걸친 이 수준의 표면적이라면, 규약에 관한 대화를 한곳에 집중하는 것이 타당합니다. 그곳은 여기입니다. https://github.com/open-telemetry/semantic-conventions
벤더 논쟁이 지연을 유발한다면, 이론적으로 여기 PR에서 이 지연을 볼 수 있어야 합니다. 그리고 그 지연이 기본적으로 바깥으로 전파되는 것도 보여야 합니다. 결론부터 말하자면, 저는 이에 대해 틀렸습니다. PR 라벨링 규약을 잘 갖춰서 이것을 훨씬 쉽게 만들어 준 OpenTelemetry 사람들에게 큰 감사를 드립니다.
그러므로 semconv이 병목이라면, 그곳에서 가장 느린 PR을 살펴봅시다.
| PR | 일수 | 댓글 | 검토 | 라벨 | 주제 |
|---|---|---|---|---|---|
| #2083 | 277.5 | 17 | 115 | area:gen-ai | MCP 의미 체계 규약 |
| #2617 | 258.6 | 29 | 13 | area:gcp | GCE 인스턴스 라벨 |
| #1698 | 187.9 | 3 | 7 | area:azure, breaking | azure_ → azure. 이름 변경 |
| #2619 | 174.6 | 24 | 8 | area:gcp | GCE 인스턴스 그룹 관리자 |
| #3118 | 147.1 | 19 | 8 | area:graphql, breaking | GraphQL 권장 항목과 선택 참여 항목 |
| #1741 | 141.0 | 4 | 23 | changelog.opentelemetry.io | 메인프레임 |
| #1784 | 127.3 | 7 | 48 | area:k8s | k8s.container.status 메트릭 |
| #2287 | 118.5 | 12 | 95 | area:rpc | ONC/Sun RPC + NFS 메트릭 |
| #2179 | 117.0 | 7 | 114 | area:gen-ai, breaking | Gen-AI 채팅 기록 속성 |
네, 일부는 꽤 느리지만 복잡한 주제가 논의되고 있습니다. 하지만 흥미롭게도 이 지연은 SDK/API 영역으로 실제로 흘러들어가지 않습니다. 이는 OpenTelemetry가 이 대화를 잘 격리하고 있음을 시사합니다.
Python을 보면 가장 느린 PR은 semconv 관련이 아닙니다.
| PR | 일수 | 댓글 | 검토 | 라벨 | 주제 |
|---|---|---|---|---|---|
| #4646 | 361.1 | 5 | 19 | — | OpAMP 통합 스케치 |
| #4576 | 314.0 | 11 | 27 | Stale | OTLP HTTP max_export_batch_size |
| #4609 | 253.7 | 2 | 9 | — | 환경 캐리어 |
| #4709 | 172.1 | 8 | 40 | — | http 익스포터 오류 처리 |
| #4333 | 164.9 | 6 | 4 | — | GRPC 익스포터 백오프 구성 |
| #4654 | 161.7 | 7 | 14 | log-breaking-changes | events API/SDK 사용 중단 |
| #4863 | 155.0 | 5 | 36 | — | 런타임에 메트릭 리더 추가/제거 |
| #4647 | 152.9 | 4 | 9 | Approve Public API check, log-breaking-changes | Log → LogRecord 이름 변경 |
| #4854 | 150.5 | 7 | 9 | hold | W3C traceparent random-trace-id |
| #4676 | 126.4 | 20 | 30 | Approve Public API check, log-breaking-changes | logs SDK 리팩터링 |
실제로 이들의 지연은 다른 유지관리자를 필요로 하는 Approve Public API check가 부과하는 추가 필수 검사 때문입니다. 하지만 그것은 적절해 보이며, 우리를 초기 문제인 “유지관리자가 충분하지 않다”로 되돌려 놓습니다.
이 모든 것을 살펴본 뒤 패턴은 분명해집니다. OpenTelemetry에서 새 기능이 최종 사용자에게 도달하는 데 매우 오랜 시간이 걸리는 이유는, 비교적 제한된 인력층과 결합해 안정성을 매우 심각하게 다루기 때문입니다. 항목이 전체 스택을 통과하면, API 구현과 그 API 변경을 최종 사용자에게 전달하는 일은 과로한 유지관리자 집단에 떨어집니다. 그러면 우리는 무엇을 해야 할까요?
살펴볼 가치가 있는 한 가지 아이디어는 기간이 정해진 베타 계층을 추가하는 것입니다. 기본적으로 아래 다이어그램의 “Experimental”과 “Stable” 사이에 두는 것입니다. 문제는 최종 사용자에게 Experimental 기능을 사용하기 위한 추가 단계 때문에, 그것들은 없는 것이나 마찬가지라는 점입니다. 우리 중 99%는 experimental 기능이 언제 추가되는지 알지 못하며, 결코 그것에 참여하지 않을 것입니다. 하지만 기능이 제거 없이 최소 12개월은 유지되고 최종 사용자로서 더 쉽게 접근할 수 있다는 것을 안다면, 프로젝트가 실제로 더 실행 가능한 피드백을 얻는 데 도움이 될 수 있습니다.
기본적으로 기능은 Experimental(매우 낮은 사용량) -> Beta(Experimental보다 최종 사용자에게 더 노출됨) -> 12개월 -> 제거 또는 Stable 순서로 갈 것입니다.
혼란스럽게도 Beta는 OTel에 존재하지만, 구성 요소가 아니라 SDK에 사용됩니다. Rust는 Beta이지만 Profiles는 Beta일 수 없는 듯합니다. 솔직히 어떤 라벨이 어떤 것에 적용되어야 하는지 알아내는 것은 거의 불가능합니다. 아무도 정말로 모르는 것 같습니다. 아래는 SDK에만 적용되는 것으로 생각되는 Beta 설명입니다.
개발
구성 요소의 모든 부분이 아직 갖춰진 것은 아니며, 아직 사용자가 이용하지 못할 수도 있습니다. 버그와 성능 문제는 보고될 것으로 예상됩니다. 구성 옵션, 구성 요소 관측성, 기술적 구현 세부 사항, 구성 요소의 계획된 사용 사례 등 구성 요소의 UX에 관한 사용자 피드백이 바람직합니다. 상황이 어떻게 발전하는지에 따라 구성 옵션은 자주 호환성을 깨뜨릴 수 있습니다. 이 구성 요소는 프로덕션에서 사용해서는 안 됩니다. 사전 통지 없이 제거될 수 있습니다.
알파
기본 수준입니다. 명시적 성숙도 수준이 없는 모든 구성 요소는 “알파”로 간주해야 합니다. 구성 요소는 제한적인 비핵심 프로덕션 워크로드에서 사용할 준비가 되어 있으며, 이 구성 요소의 작성자는 사용자 피드백을 환영합니다. 버그와 성능 문제 보고가 권장되지만, 구성 요소 소유자가 즉시 처리하지 않을 수 있습니다. 구성 요소의 인터페이스와 구성 옵션은 이전 버전과의 호환성 보장 없이 자주 변경될 수 있습니다. 이 단계의 구성 요소는 통지 없이 언제든 폐기될 수 있습니다.
베타
알파와 같지만, 인터페이스(API, 구성, 생성된 텔레메트리)는 가능한 한 안정적으로 취급됩니다. 릴리스 사이에 호환성을 깨는 변경이 있을 수 있지만, 구성 요소 소유자는 이를 최소화해야 합니다. 이 단계의 구성 요소는 알파 단계 동안 이미 비핵심 프로덕션 워크로드에 노출된 것으로 예상되므로 더 폭넓은 사용에 적합합니다.
릴리스 후보
구성 요소는 기능이 완성되었고 더 폭넓은 사용을 위한 준비가 되었습니다. 안정적이라고 선언할 준비가 되었으며, 그렇게 되기 전에 더 많은 프로덕션 환경에서 테스트만 필요할 수 있습니다. 버그와 성능 문제가 보고될 것으로 예상되며, 구성 요소 소유자가 이를 처리할 것이라는 기대가 있습니다. 구성 옵션과 구성 요소의 출력을 포함한 호환성 파괴 변경은 특별한 상황에서만 허용됩니다. 가능한 경우 사용자에게 호환성 파괴 변경을 사전에 알려야 합니다.
안정
구성 요소는 일반 제공을 위한 준비가 되었습니다. 버그와 성능 문제를 보고해야 하며, 구성 요소 소유자가 이를 처리할 것이라는 기대가 있습니다. 구성 옵션과 구성 요소의 출력을 포함한 호환성 파괴 변경은 특별한 상황에서만 허용됩니다. 가능한 경우 사용자에게 호환성 파괴 변경을 사전에 알려야 합니다.
사용 중단
이 구성 요소의 개발은 중단되었습니다. 새 버전은 계획되지 않았으며, 구성 요소는 포함된 배포판에서 제거될 수 있습니다. 중요 보안 문제를 제외한 새 이슈는 처리되지 않을 가능성이 높습니다. 배포판에 포함된 구성 요소는 둘 중 더 늦는 시점, 즉 최소 두 개의 마이너 릴리스 또는 6개월 동안 존재할 것으로 예상됩니다. 또한 구체적 버전 번호 또는 “2023-08-01 이후 첫 번째 릴리스”와 같은 릴리스 날짜로, 어느 버전에서 제거되는지 반드시 알려야 합니다.
유지관리되지 않음
유지관리되지 않는 것으로 식별된 구성 요소에는 활성 코드 소유자가 없습니다. 이러한 구성 요소는 코드 소유자가 한 번도 할당되지 않았거나, 이전에 활동하던 코드 소유자가 연락 후 6주 이내에 피드백 요청에 응답하지 않았을 수 있습니다. 유지관리되지 않는 구성 요소의 이슈와 풀 리퀘스트에는 그러한 라벨을 붙여야 합니다. 유지관리되지 않은 지 6개월이 지나면 이러한 구성 요소는 사용 중단될 수 있습니다. 유지관리되지 않는 구성 요소는 코드 소유자가 될 기여자를 적극적으로 찾고 있습니다.
추가로, Go와 Ruby가 같은 기준으로 유지관리되고 있다고 암시하는 것은 정중히 말해 오해의 소지가 있습니다. 이것은 Ruby 사람들을 비난하려는 것이 아닙니다. 그들은 가진 것으로 영웅적인 일을 하고 있습니다. 하지만 그렇지 않은데 동등성이 존재하는 척하면, 한 경험을 기대하고 왔다가 다른 경험을 얻는 사용자가 생길 때 혼란과 조용한 분노만 만들어 냅니다. 유지관리 계층에 대해 솔직해지면 사람들이 정보에 근거한 선택을 하게 할 수 있고, 문제를 공개적으로 명명함으로써 다른 계층에 더 많은 도움을 끌어들일 수도 있습니다.
마지막으로 “더 많은 유지관리자가 필요하다”는 관점에서 OpenTelemetry의 이런 문제를 더 공개적으로 드러내려 할 것입니다. 이 일을 하는 사람들은 아마 문제가 있다는 것을 알고 있었겠지만, 커뮤니티 전체는 솔직히 더 적극적이고, 이상적으로는 독립적인 유지관리자와 기여자가 필요하다는 사실을 전혀 모르는 듯합니다.
OpenTelemetry는 훌륭한 일을 하는 훌륭한 프로젝트입니다. 이 정도 규모에서 이 정도로 적은 인원으로, 솔직히 영웅적인 일을 하고 있습니다. 하지만 벤더 전용 SDK를 실제로 대체하려면 안정성 계약과 언어 수 측면에서 현실적으로 무엇을 할 수 있는지에 대해 조금 더 실용적으로 접근해야 한다고 생각합니다. 변경 사항이 잘 전달되기만 한다면 호환성 파괴 변경은 이 약속들이 시사하는 것만큼 커뮤니티에 파괴적이지 않다고 생각하며, 이렇게 얇은 유지관리 인력층에서는 무언가를 양보해야 합니다.
어쨌든 제 데이터의 정확성을 자유롭게 확인해 보시고, 문제가 발견되면 알려 주세요!