Годами при попытке перетащить команду с вендорского SDK на OpenTelemetry приходится слышать одну и ту же жалобу в разных вариациях: «почему кажется, что это всё ещё не готово?»
Вендорские SDK для observability, если говорить откровенно, рассчитаны на полного новичка. Устанавливаешь — дашборды сами подгружают данные, о том, как всё это устроено внутри, беспокоится кто-то другой, а сам просто живёшь дальше. OpenTelemetry, напротив, встречает пользователя целой россыпью пометок «experimental» и примерно шестью разными способами сделать одно и то же.
В защиту OpenTelemetry стоит сказать: проект никогда и не ставил себе такую цель. Заслуживает уважения то, что команда не отступила от идеи построить по-настоящему вендор-агностичную систему, которой действительно всё равно, что делают с данными. Ни разу не возникло ощущения, что какой-то вендор получает особое предпочтение — а это немалое достижение, учитывая, насколько прибыльной и конфликтной была и остаётся индустрия observability. Тем более что мейнтейнеры проекта по большей части работают как раз в этих компаниях.
Со временем стало появляться беспокойство. Обсуждения в репозитории semantic-conventions растягиваются до бесконечности. Разные языки живут совершенно разными жизнями: Golang и .NET — граждане первого сорта, остальные языки отстают на годы.
Пришлось начать задавать много уточняющих вопросов, прежде чем рекомендовать OpenTelemetry небольшим командам, у которых нет времени, бюджета или запаса терпения на это. Автоинструментация — вещь по-настоящему волшебная, но обрыв между «автоинструментация работает» и «теперь нужно вручную что-то доинструментировать» настолько крутой, что людей стоит предупреждать заранее.
Этот сюжет крутится в мире observability уже давно — смутное ощущение, что «что-то не так в стране Otel». Но попробуем всё же получить реальные данные. Есть ли проблема на самом деле, или это лишь субъективное ощущение сообщества о медленном прогрессе? Дело в нехватке мейнтейнеров, слишком большом охвате, или в чём-то среднем?
Первоначальная гипотеза звучала так: «классический случай, когда open source откусил больше, чем может прожевать». Отчасти это так — не хватает мейнтейнеров, не хватает бюджета. Но есть и кое-что ещё.
Реальная проблема внутри OpenTelemetry — это столкновение трёх факторов одновременно. Есть жёсткий гейт стабильности, который в сочетании с очень небольшой скамейкой реальных мейнтейнеров порождает вполне понятную осторожность при переводе фичи из статуса experimental. Добавьте к этому колоссальный охват языков и фреймворков, которые проект пытается покрыть. В итоге получается идеальный шторм: появляется стимул до бесконечности спорить о потенциальных проблемах, которые может создать та или иная фича, — ведь как только она зафиксирована и выпущена как stable, изменить её уже нельзя.
Как устроен OpenTelemetry
На данный момент OpenTelemetry пытается поддерживать головокружительное количество языков и фреймворков.

OpenTelemetry — гигантский проект. Он охватывает десятки языков, сотни библиотек и бесчисленное множество бэкендов. Чтобы всё это не превратилось в хаос, работа делится на два лагеря:
- Core → поддерживается напрямую проектом OTel. Небольшой, стабильный, вендор-нейтральный, проходит жёсткое ревью. Это поверхность, «определяющая спецификацию».
- Contrib → вклад сообщества и вендоров. Шире, движется быстрее, покрывает длинный хвост интеграций.
Есть ещё otel-collector — компонент, который работает рядом и отправляет логи, метрики и трейсы. Он повторяет тот же паттерн. Но применительно к языкам речь именно об этом разделении core/contrib.
opentelemetry-python (core) | API, SDK, экспортёр OTLP, распространение контекста, примитивы определения ресурсов |
opentelemetry-python-contrib | Библиотеки инструментации для Flask, Django, requests, psycopg2, Redis, Kafka, boto3 и так далее |
То, что ломается, отправляется в contrib, то, что не ломается — в core.
Из этого и возникает конфликт. contrib — это колоссальный избыток для большинства проектов. Никто не хочет устанавливать 300 экспортёров ради одного нужного. На стороне языков это не такая большая проблема: pip install opentelemetry-instrumentation-flask даёт всё необходимое для Flask. А вот со стороны коллектора приходится либо использовать OpenTelemetry Collector Builder, чтобы собрать свой коллектор, либо просто плыть по течению и надеяться, что всё сработает. Существование такого инструмента — это круто, но это слишком большой объём работы, который приходится взваливать на команду.
Процесс добавления новой фичи
Ниже — попытка восстановить процесс добавления новой фичи в OTel. Проверить эту реконструкцию можно самостоятельно:
- OpenTelemetry Enhancement Proposal (OTEP) (репозиторий)
- После принятия OTEP текст попадает в директорию Specification того же репозитория.
- Дальше, судя по всему, идёт этап Semantic conventions. Именно здесь обсуждаются конкретные детали и происходят самые долгие дискуссии. На этом этапе речь фактически о постоянном закреплении дизайна, после чего изменить его становится очень тяжело.
- Каждый SDK реализует API-поверхность, определённую в спецификации. Некоторые SDK уже пошли на breaking-изменения версии 2.0, так что похоже, прежний настрой «никаких 2.0 любой ценой» отброшен — и это, кажется, разумное и правильное решение.
- Contrib / инструментация. Здесь всё немного более размыто. Похоже, эти пакеты должны следовать за последней версией API/SDK, но каждый contrib-пакет может версионироваться независимо, что делает дизайн более гибким.
- Collector + OTLP. Данные должны куда-то попасть. У OTLP (протокола передачи) свой жизненный цикл стабильности и своя спецификация (здесь). У компонентов коллектора статус стабильности описан в их README, и, насколько можно судить, там царит полный разнобой.
Что осталось не до конца ясным
- Непонятно, сколько времени занимает переход OTEP → Specification. История коммитов в Git не даёт никакого предсказуемого числа или цикла.
- Не до конца понятно, как соотносятся между собой все эти обязательства по стабильности. Работают ли группы Collector и OTLP синхронно? Может ли язык «выпасть из охвата», если слишком сильно отстанет?
Попытка проверить гипотезу
Поскольку OpenTelemetry — проект CNCF, логичнее всего сравнить его с другими проектами CNCF. В качестве базы для сравнения взяты Envoy и Prometheus. Использован не самый идеальный самописный Python-скрипт, который применялся раньше для измерения «здоровья» open-source проектов. Ссылка на сырые данные без графиков прилагается — можно проверить самостоятельно и, скорее всего, найти изъян в методике.

Если посмотреть на активность Envoy за 24 месяца, видно вполне здоровый проект: хорошее распределение авторов, тех, кто мержит PR, тех, кто закрывает issue. phlax, очевидно, занимает важное место в проекте, но в целом есть достаточная скамейка людей, готовых подключиться при необходимости. Известный бот-трафик был отфильтрован.
Теперь сравним с одним из языков OpenTelemetry. Больше всего профессионального опыта накоплено с Golang и Python, но по отзывам сообщества, у Ruby и PHP дела обстоят гораздо хуже. Вот статистика PHP за тот же период.

Видно совершенно отчётливо: почти вся активность сосредоточена на двух людях. Это нельзя назвать здоровым open-source проектом — очевидно, что людей не хватает для того охвата, который должен обеспечивать OTel. С Ruby ситуация аналогичная.

Для сравнения — «сильнейшие» SDK OpenTelemetry, Golang и .NET (хотя и Python держится неплохо), выглядят гораздо здоровее.
Golang


Первая проблема, пожалуй, не вызывает удивления: слишком большая концентрация вокруг слишком малого числа мейнтейнеров. Авторы кода не должны одновременно быть теми, кто мержит PR и закрывает issue — в идеале эти задачи стоило бы распределять более равномерно.
Стоит отдать должное мейнтейнерам: они хорошо справляются с тем, чтобы держать обсуждения публичными. Публичные протоколы встреч разных рабочих групп мейнтейнеров нашлись без труда, и по ним легко проследить, что происходит. Не создаётся впечатления, что мейнтейнеры пытаются помешать людям участвовать в проекте — скорее требования к стабильности практически заморозили проект на месте.
Проблема больше похожа на классический случай «кто-то должен платить мейнтейнерам». Проект слишком сложен, чтобы реалистично заниматься им в качестве хобби. Любой проект, берущий на себя такие долгосрочные обязательства по стабильности, не может рассчитывать на помощь сообщества энтузиастов-хоббистов. Невозможно бесплатно участвовать в звонках и выполнять то, что ожидается от участника проекта такого масштаба и значимости. Но это же означает, что на людей, выполняющих эту критически важную работу, давят ожидания их работодателей.
| Репозиторий | Смерженные PR за 24 мес. | Уникальных мержеров | Доля топ-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% | Всего два мержера |
semantic-conventions | 911 | 9 | 49,7% | Один человек (lmolkova) |
opentelemetry-go | 686 | 5 | 36,9% | Распределённая скамейка |
opentelemetry-dotnet | 657 | 6 | 31,5% | Распределённая скамейка |
prometheus | 1849 | 31 | 14,4% | Широкая скамейка |
envoy | 5432 | 28 | 35,8% | Широкая скамейка |
Итак, во всех этих SDK слишком мало мейнтейнеров. Но это не объясняет полностью, почему новые фичи так долго проходят весь путь. Гипотеза заключалась в том, что где-то между подачей идеи и её формализацией разворачивается бесконечная дискуссия.
Соглашения о семантике
При таком охвате разных фреймворков и языков логично сосредоточить обсуждение соглашений в одном месте. Оно происходит здесь: semantic-conventions.
Если замедление вызвано спорами вендоров, оно теоретически должно быть заметно в PR именно там, а дальше распространяться по всей цепочке. Спойлер: гипотеза не подтвердилась. Отдельное спасибо команде OpenTelemetry за аккуратную систему меток на PR, которая сильно облегчила анализ.
Если 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 Recommended vs Opt-In |
| #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 |
Да, некоторые PR действительно очень медленные, но обсуждаются в них действительно сложные темы. Интересно, что это замедление никак не просачивается в область SDK/API — похоже, OpenTelemetry неплохо справляется с изоляцией таких дискуссий.
Если посмотреть на Python, самые медленные PR там вообще не связаны с semconv.
| PR | дней | комментариев | ревью | метки | тема |
|---|---|---|---|---|---|
| #4646 | 361,1 | 5 | 19 | — | набросок интеграции OpAMP |
| #4576 | 314,0 | 11 | 27 | Stale | max_export_batch_size для OTLP HTTP |
| #4609 | 253,7 | 2 | 9 | — | env carrier |
| #4709 | 172,1 | 8 | 40 | — | обработка ошибок http-экспортёра |
| #4333 | 164,9 | 6 | 4 | — | настройка backoff для GRPC-экспортёра |
| #4654 | 161,7 | 7 | 14 | log-breaking-changes | депрекация Events API/SDK |
| #4863 | 155,0 | 5 | 36 | — | добавление/удаление metric readers в рантайме |
| #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 и доведение изменений до конечного пользователя ложится на перегруженный пул мейнтейнеров. Что с этим делать?
Одна из идей, заслуживающих внимания — добавить какой-то временной бета-уровень между «Experimental» и «Stable» на схеме ниже. Проблема в том, что для конечных пользователей, из-за дополнительных шагов, необходимых для использования experimental-фич, они практически не существуют. 99% пользователей понятия не имеют, когда добавляется экспериментальная фича, и никогда с ней не столкнутся. Но если бы было известно, что фича продержится минимум 12 месяцев без удаления и будет более доступна для конечного пользователя, это реально помогло бы проекту получать более полезную обратную связь.

По сути, фича проходила бы путь: Experimental (низкое использование) → Beta (более открыта для конечного пользователя, чем Experimental) → 12 месяцев → удаление или Stable.
Что любопытно и немного запутывает: статус Beta в Otel уже существует, но применяется к SDK, а не к компонентам. Так, Rust имеет статус Beta, а вот Profiles, похоже, не может иметь статус Beta. Разобраться, какие метки к чему применяются, практически невозможно. Подозрение — что этого толком не знает никто. Ниже — описание статуса Beta, которое, судя по всему, применимо только к SDK.
Development
Not all pieces of the component are in place yet, and it might not be available for users yet. Bugs and performance issues are expected to be reported. User feedback around the UX of the component is desired, such as for configuration options, component observability, technical implementation details, and planned use-cases for the component. Configuration options might break often depending on how things evolve. The component SHOULD NOT be used in production. The component MAY be removed without prior notice.
Alpha
This is the default level: any components with no explicit maturity level should be assumed to be "Alpha". The component is ready to be used for limited non-critical production workloads, and the authors of this component welcome user feedback. Bugs and performance problems are encouraged to be reported, but component owners might not work on them immediately. The component's interface and configuration options might often change without backward compatibility guarantees. Components at this stage might be dropped at any time without notice.
Beta
Same as Alpha, but the interfaces (API, configuration, generated telemetry) are treated as stable whenever possible. While there might be breaking changes between releases, component owners should try to minimize them. A component at this stage is expected to have had exposure to non-critical production workloads already during its Alpha phase, making it suitable for broader usage.
Release Candidate
The component is feature-complete and ready for broader usage. The component is ready to be declared stable, it might just need to be tested in more production environments before that can happen. Bugs and performance problems are expected to be reported, and there's an expectation that the component owners will work on them. Breaking changes, including configuration options and the component's output, are only allowed under special circumstances. Whenever possible, users should be given prior notice of the breaking changes.
Stable
The component is ready for general availability. Bugs and performance problems should be reported, and there's an expectation that the component owners will work on them. Breaking changes, including configuration options and the component's output, are only allowed under special circumstances. Whenever possible, users should be given prior notice of the breaking changes.
Deprecated
Development of this component is halted. No new versions are planned, and the component might be removed from its included distributions. Note that new issues will likely not be worked on except for critical security issues. Components that are included in distributions are expected to exist for at least two minor releases or six months, whichever happens later. They also MUST communicate in which version they will be removed, either in terms of a concrete version number or the date of a release, like: "the first release after 2023-08-01".
Unmaintained
A component identified as unmaintained does not have an active code owner. Such components may have never been assigned a code owner, or a previously active code owner has not responded to requests for feedback within 6 weeks of being contacted. Issues and pull requests for unmaintained components SHOULD be labeled as such. After 6 months of being unmaintained, these components MAY be deprecated. Unmaintained components are actively seeking contributors to become code owners.Кроме того, при всём уважении, вводит в заблуждение сама идея, что Go и Ruby поддерживаются на одном и том же уровне. Это не упрёк в адрес Ruby-сообщества — они делают героическую работу с тем, что у них есть. Но притворяться, что паритет существует там, где его нет, лишь порождает путаницу и тихое недовольство, когда пользователь приходит, ожидая одного опыта, а получает совсем другой. Честность в отношении уровней поддержки позволила бы людям делать осознанный выбор и, возможно, привлекла бы больше помощи к отстающим направлениям — если проблему назвать вслух.
Наконец, стоило бы более открыто поднимать эти проблемы внутри OpenTelemetry именно с позиции «нам нужно больше мейнтейнеров». Люди, непосредственно занятые этой работой, судя по всему, знали о проблеме, но у широкого сообщества, похоже, нет никакого представления о том, что нужны более вовлечённые, в идеале независимые мейнтейнеры и контрибьюторы.
OpenTelemetry — отличный проект, который делает отличную работу. Честно говоря, это героическая работа при таком масштабе и таком скромном числе людей. Но чтобы действительно заменить вендорские SDK, стоит стать чуть более прагматичными в отношении реалистичности обязательств по стабильности и количества поддерживаемых языков. Breaking-изменения едва ли настолько разрушительны для сообщества, насколько подразумевают эти обещания — при условии, что о них хорошо сообщают заранее. А при такой тонкой скамейке мейнтейнеров чем-то придётся пожертвовать.
Все желающие могут проверить исходные данные на точность и сообщить о найденных проблемах.