Декодер traceparent — W3C Trace Context
Хватит считать hex-цифры. Бесплатный онлайн-декодер traceparent — работает в браузере, ничего не уходит. Trace ID, span ID, 8 бит trace-flags, tracestate, Datadog/X-Ray/B3.
- Версия
00- Trace ID
4bf92f3577b34da6a3ce929d0e0e4736- Parent ID (span ID)
00f067aa0ba902b7- Trace flags
01
| Бит | Маска | Название | Состояние |
|---|---|---|---|
| 0 | 0x01 | sampled | 1 |
| 1 | 0x02 | random-trace-id | 0 |
| 2 | 0x04 | reserved | 0 |
| 3 | 0x08 | reserved | 0 |
| 4 | 0x10 | reserved | 0 |
| 5 | 0x20 | reserved | 0 |
| 6 | 0x40 | reserved | 0 |
| 7 | 0x80 | reserved | 0 |
Читайте эти биты побитовым И. Сравнение всего байта с 01 неверно отчитается о любой трассировке, которая несёт ещё и зарезервированный бит.
- x-datadog-trace-id
11803532876627986230- x-datadog-tags: _dd.p.tid
4bf92f3577b34da6- x-datadog-parent-id
67667974448284343- AWS X-Ray trace ID
1-4bf92f35-77b34da6a3ce929d0e0e4736- b3 (single header)
4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1- X-B3-TraceId
4bf92f3577b34da6a3ce929d0e0e4736- X-B3-SpanId
00f067aa0ba902b7- X-B3-Sampled
1
Datadog передаёт младшие 64 бита trace ID десятичной строкой, а старшие 64 бита — шестнадцатеричными в теге. Передача всех 128 бит одним десятичным числом — классическая причина, по которой trace ID из логов ничего не находит в интерфейсе.
Идентификатор X-Ray содержит 32-битную метку времени, а W3C trace ID вообще не несёт метки времени. Дата ниже имеет смысл, только если идентификатор действительно родом из X-Ray.
| # | Ключ | Значение | Статус |
|---|---|---|---|
| 1 | rojo | 00f067aa0ba902b7 | OK |
| 2 | congo | t61rcWkgMzE | OK |
Формат traceparent: анатомия полей
| Поле | Шестнадцатеричные цифры | Байты | Значение | Недопустимое значение |
|---|---|---|---|---|
| version | 2 | 1 | Версия формата. Сегодня всегда 00; ff запрещено. | ff |
| trace-id | 32 | 16 | Идентифицирует всю трассировку от начала до конца. | Одни нули |
| parent-id | 16 | 8 | Идентифицирует вызывающий спан, а не запрос. | Одни нули |
| trace-flags | 2 | 1 | 8-битное поле — читайте его бит за битом, а не как булево значение. | — |
Значения trace-flags: разбор 00, 01, 02 и 03
| Шестнадцатеричное | Двоичное | sampled | random-trace-id | Значение |
|---|---|---|---|---|
| 00 | 00000000 | 0 | 0 | Выше по цепочке решили не брать в выборку — смотрите на вызывающего, а не на свой сервис. |
| 01 | 00000001 | 1 | 0 | Записано штатно. Это встречается чаще всего. |
| 02 | 00000010 | 0 | 1 | Случайный trace ID объявлен, но выборка не ведётся. |
| 03 | 00000011 | 1 | 1 | Записано, и trace ID объявлен равномерно случайным. |
bit 0 — Вызывающая сторона записала эту трассировку. Сброшенный бит означает, что она осознанно этого не сделала.
bit 1 — Level 2: крайние правые 7 байт trace ID равномерно случайны.
bit 2-7 — Зарезервировано. Следует игнорировать при приёме и сбрасывать в исходящих запросах.
Сделано напрямую по рекомендации W3C Trace Context и кандидатской рекомендации Level 2; парсер покрыт модульными тестами для каждой допустимой и недопустимой формы, названной в спецификации.
Что такое заголовок traceparent?
traceparent — это HTTP-заголовок, который переносит распределённую трассировку от одного сервиса к следующему. До стандартизации каждый вендор трассировки распространял контекст в собственном заголовке, поэтому запрос, пересекавший системы, терял свою идентичность на границе. Спецификация W3C Trace Context закрыла эту проблему единым и намеренно компактным форматом: version-trace-id-parent-id-trace-flags — четыре шестнадцатеричных поля, соединённых дефисами, всего 55 символов в текущей версии.
У каждого поля одна задача. Version сегодня всегда 00, а ff запрещено прямым текстом. Trace-id — это 16 байт, идентифицирующих весь запрос от начала до конца; оно остаётся неизменным на каждом переходе. Parent-id — это 8 байт, идентифицирующих спан непосредственно вызывающей стороны, поэтому, в отличие от trace-id, оно меняется на каждом переходе. Байт trace-flags — место, где живёт большая часть путаницы: он выглядит булевым, потому что 01 встречается гораздо чаще прочих значений, но это восемь бит. Бит 0 — sampled. Бит 1, добавленный в Trace Context Level 2, — это random-trace-id: он утверждает, что крайние правые семь байт trace ID равномерно случайны, и потому системы ниже по цепочке могут вести по ним выборку или шардирование. Оставшиеся шесть бит зарезервированы, и ровно поэтому поле нужно читать побитовым И, а не сравнивать на равенство.
Соседний заголовок tracestate несёт рядом с ним пары ключ-значение, специфичные для вендоров, с потолком в 32 элемента. Этот потолок объясняет загадочный симптом: данные вендора есть на границе сети и пропадают несколькими переходами позже, потому что посредники начали отбрасывать записи, как только список перерос лимит. По-настоящему универсальным заголовок стал после того, как его принял OpenTelemetry, и эта страница разбирает его целиком — поля, биты, элементы tracestate и эквивалентные идентификаторы для других форматов распространения контекста — ничего никуда не отправляя.
# The header as it travels on the wire
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE
# Read the four fields apart
# version 00
# trace-id 4bf92f3577b34da6a3ce929d0e0e4736 (16 bytes, whole request)
# parent-id 00f067aa0ba902b7 (8 bytes, calling span)
# trace-flags 01 (bit 0 set = sampled)
# Send one yourself
$ curl -H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01' \
https://example.com/api Ключевые возможности
Каждое поле отдельно и с копированием
Version, trace-id, parent-id и trace-flags получают собственную строку и собственную кнопку копирования, поэтому перенести 32-символьный trace ID в запрос — это один клик вместо аккуратного выделения мышью.
Trace-flags читаются как восемь бит
Байт флагов раскладывается на все восемь позиций с их шестнадцатеричными масками. Бит 0 — sampled, бит 1 — флаг random-trace-id из Level 2, а зарезервированные биты показаны, а не отброшены молча.
Перевод в Datadog, X-Ray и B3
Младшие 64 бита как десятичный trace ID для Datadog, старшие 64 бита как тег, который едет вместе с ним, форма X-Ray вида 1-{8}-{24} и обе раскладки B3 — одно- и многозаголовочная. Всё считается через BigInt, поэтому ничего не переполняется.
Диагноз, а не только вердикт
Trace ID из одних нулей объясняется как трассировка, которая так и не инициализировалась, а сброшенный бит sampled — как решение, принятое выше по цепочке. Понять, с чем из двух вы имеете дело, обычно и есть весь сеанс отладки.
Tracestate с потолком в 32 элемента
Элементы перечисляются с проверкой ключа и значения по каждому в отдельности и со счётчиком относительно лимита из спецификации — того самого лимита, который объясняет, почему данные вендора исчезают несколькими переходами ниже.
Ничего не покидает браузер
Разбор — это обычные операции со строками и арифметика BigInt без зависимостей и сетевых вызовов, что подтверждается автоматическим контрактным тестом при каждой сборке. Копирование ссылки использует фрагмент URL, который никогда не передаётся.
Примеры traceparent с разбором
Пример из самой спецификации, разобранный
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
version 00 · trace-id 4bf92f3577b34da6a3ce929d0e0e4736 · parent-id 00f067aa0ba902b7 · trace-flags 01 (sampled)
Четыре поля через дефис, всего 55 символов для версии 00. Поле trace-id идентифицирует весь запрос, пока он идёт через все сервисы; parent-id — его часто называют span ID — идентифицирует только непосредственно вызывающую сторону, поэтому меняется на каждом переходе, а trace-id остаётся прежним. Завершающее 01 — это полный байт, а не булево значение: бит 0 установлен, значит вызывающая сторона записала эту трассировку.
trace-flags 00 — вызывающая сторона решила не записывать
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
Заголовок корректен · бит sampled сброшен
Этот заголовок полностью корректен, и в этом вся суть. Сброшенный бит sampled — это указание сверху по цепочке, а не дефект вашего сервиса: тот, кто вас вызвал, отработал свой сэмплер и решил не записывать. Поиски пропавших спанов в собственной конфигурации отнимают здесь часы. Правильный вопрос звучит иначе: какой сервис вас вызывает, присылает родительский спан и решает не отправлять трассировку в выборку.
trace ID из одних нулей означает, что трассировка так и не началась
00-00000000000000000000000000000000-00f067aa0ba902b7-01
Некорректно — trace-id из одних нулей
Спецификация объявляет trace-id из одних нулей недопустимым и требует игнорировать весь traceparent целиком. Полезно понимать, о чём это говорит на практике: не «трассировка, у которой пока нет данных», а SDK, который так и не был инициализирован, либо промежуточный слой, подставляющий заголовок-заглушку. То же правило действует и для parent-id из одних нулей.
Тот же trace ID в формате Datadog
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
x-datadog-trace-id 11803532876627986230 · _dd.p.tid 4bf92f3577b34da6
Datadog передаёт младшие 64 бита 128-битного trace ID десятичной строкой, а старшие 64 бита — шестнадцатеричным значением в отдельном теге. Если подать все 128 бит как одно десятичное число, получится идентификатор, который не совпадает ни с чем; именно поэтому это преобразование снова и снова всплывает в трекерах ошибок трассировщиков. Младшая половина здесь — a3ce929d0e0e4736, а 64 бита выходят за пределы того, что вмещает число в JavaScript, поэтому страница считает через BigInt.
Как пользоваться декодером traceparent
- 1
Вставьте заголовок traceparent
Достаточно вставить сырое значение заголовка — например, 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01. Декодирование идёт по мере ввода, никаких кнопок нажимать не нужно.
- 2
Прочитайте четыре поля по отдельности
Version, trace-id, parent-id и trace-flags разносятся по своим строкам, у каждой своя кнопка копирования, так что перенести в запрос один только trace ID можно, не выделяя вручную 32 символа.
- 3
Проверьте флаги бит за битом
Байт trace-flags раскладывается на все восемь бит вместе с их масками, поэтому sampled и флаг random-trace-id из Level 2 видны по отдельности, а не спрятаны внутри двухсимвольного значения.
- 4
Переведите в формат вашего бэкенда
Ниже формируются идентификаторы Datadog, AWS X-Ray и оба варианта B3, включая десятичный trace ID из младших 64 бит, который ждёт Datadog, и тег со старшими 64 битами, путешествующий рядом с ним.
- 5
Добавьте tracestate и поделитесь результатом
Вставьте заголовок tracestate, чтобы получить список его элементов с проверкой каждого и счётчиком относительно лимита в 32 элемента, а затем нажмите копирование ссылки, чтобы зафиксировать точное состояние в URL для тикета.
Частые ошибки с traceparent
Сравнение всего байта флагов с 01
Так восьмибитное поле трактуется как перечисление. У трассировки, которая попала в выборку и вдобавок несёт флаг random-trace-id из Level 2, флаги равны 03, и проверка на равенство отчитается о ней как о невыбранной.
if (traceFlags === 0x01) { record(); } if (traceFlags & 0x01) { record(); } Перевод всех 128 бит в одно десятичное число
Datadog ждёт младшие 64 бита десятичными, а старшие 64 бита — шестнадцатеричными в отдельном теге. Передача всего значения одним десятичным числом даёт идентификатор, который ничему не соответствует.
x-datadog-trace-id: 100985939111033328018442752961257817910
x-datadog-trace-id: 11803532876627986230 x-datadog-tags: _dd.p.tid=4bf92f3577b34da6
Отклонение любой версии, кроме 00
Спецификация просит парсеры прочитать из более высокой версии то, что они распознают, и стерпеть лишние поля. Отклонение с ходу начинает трассировку заново и рвёт связь через границу.
if (version !== '00') throw new Error('bad traceparent'); if (version !== '00' && header.length >= 55) { /* parse the known prefix */ } Отправка шестнадцатеричных цифр в верхнем регистре
Грамматика допускает только нижний регистр. Trace ID заглавными буквами несёт правильное значение и всё равно отвергается соответствующим спецификации получателем, из-за чего эту ошибку особенно неприятно вылавливать глазами.
traceparent: 00-4BF92F3577B34DA6A3CE929D0E0E4736-00F067AA0BA902B7-01
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
Что можно делать декодером traceparent
- Понять, почему у трассировки нет спанов
- Вставьте входящий заголовок и прочитайте бит sampled. Если он сброшен, трассировку и не собирались записывать, а ответ лежит на стороне вызывающего, а не вашей инструментации, — различие, которое экономит массу времени на аудит собственной конфигурации сэмплирования.
- Найти трассировку, которую не находит бэкенд
- Если trace ID, скопированный из логов приложения, ничего не возвращает в Datadog, виноват обычно формат. Переведите его здесь, чтобы увидеть десятичный идентификатор из младших 64 бит, которого ждёт API, вместе с тегом из старших 64 бит, обязанным его сопровождать.
- Проверить заголовки, которые подставляет шлюз
- Прокси и service mesh формируют контекст трассировки на входе. Вставьте то, что пришло на самом деле, и подтвердите длину, строчный шестнадцатеричный регистр и ненулевые идентификаторы, прежде чем считать виноватой следующую систему.
- Воспроизвести продакшен-трассировку вручную
- Возьмите заголовок из реального запроса и повторите его к стенду, чтобы пройти по той же трассировке. Собрать запрос удобно в конструкторе команд curl и вставить заголовок прямо в него.
- Объяснить контекст трассировки команде
- Таблицы анатомии полей и значений trace-flags на этой странице — статический справочный материал, на который можно сослаться, а готовые кнопки показывают каждый вариант ошибки без того, чтобы кому-то пришлось ломать сервис ради демонстрации.
Как устроен валидатор W3C Trace Context
- Грамматика из четырёх полей
- Порядок такой: version, дефис, trace-id, дефис, parent-id, дефис, trace-flags — всё строчными шестнадцатеричными цифрами. В version 2 цифры, в trace-id 32, в parent-id 16, в trace-flags 2: итого 52 шестнадцатеричные цифры плюс 3 дефиса, ровно 55 символов для версии 00. Шестнадцатеричные цифры в верхнем регистре делают заголовок недопустимым, даже если само значение выглядит правильным, а trace-id и parent-id из одних нулей объявлены недопустимыми явно, а не считаются пустыми.
- Trace-flags — это битовое поле
- Бит 0 (маска 0x01) — sampled: установлен, значит вызывающая сторона могла записать данные трассировки. Бит 1 (маска 0x02), введённый в Level 2, — random-trace-id: если он установлен, как минимум крайние правые 7 байт trace-id должны быть выбраны случайно с равномерным распределением, что позволяет системам ниже по цепочке вести по ним выборку или шардирование. Биты со 2 по 7 зарезервированы, их следует игнорировать при приёме и сбрасывать в исходящих запросах. Поскольку зарезервированные биты могут присутствовать, поле нужно проверять побитовым И — проверка на равенство с 0x01 неверно отчитается о трассировке в выборке, которая несёт ещё и зарезервированный бит.
- Совместимость с будущими версиями
- Сегодня version равен 00, а ff запрещено, но парсер, отвергающий всё остальное, работает неправильно. Спецификация просит получателей всё же попытаться разобрать заголовок, если версия выше, а длина не меньше известного формата: прочитать поля, которые они распознают, и стерпеть лишние данные в конце, вместо того чтобы начинать трассировку заново. Этот декодер следует правилу: будущая версия разбирается успешно и помечается предупреждением, а не ошибкой.
- Лимиты tracestate, которые бьют в продакшене
- Не более 32 элементов списка — это жёсткая грамматическая граница: список длиннее делает заголовок недействительным, и получатели его отбрасывают. Каждый ключ не длиннее 256 символов и начинается со строчной буквы или цифры; начиная с Level 2 символ @ — обычный символ ключа, а не разделитель арендатора. Каждое значение состоит из 1–256 печатаемых символов ASCII и никогда не содержит запятой или знака равенства. Повторяющиеся ключи недопустимы, а вот пустые элементы списка спецификация разрешает явно: запятая, оставшаяся после того как посредник удалил запись, по-прежнему даёт корректный заголовок. Отдельно от этого: вендоры должны передавать не менее 512 символов объединённого заголовка; когда ради этого бюджета приходится урезать, первыми должны уходить записи длиннее 128 символов — поэтому данные многословного вендора исчезают раньше, чем у лаконичного.
Лучшие практики работы с Trace Context
- Проверяйте флаги побитовым И
- Пишите flags & 0x01, а не flags == 0x01. Шесть бит из восьми зарезервированы под будущее, и проверка на равенство начнёт неверно отчитываться о трассировках в выборке в тот момент, когда любой из них появится в реальном трафике.
- Считайте идентификатор из одних нулей сломанным конвейером
- Это не пустое значение, которое можно стерпеть. Отклоните заголовок и найдите компонент, который не смог инициализировать свой трассировщик или подставляет заглушку.
- Когда бит sampled сброшен, смотрите выше по цепочке
- Сэмплеры, наследующие решение родителя, распространяют выбор вызывающей стороны. Если трассировки пропадают, сначала определите, какой сервис присылает вам родительский спан с отключённым сэмплированием, и только потом проверяйте собственную конфигурацию.
- Держите tracestate коротким
- Потолок в 32 элемента — жёсткая грамматическая граница: превысили, и заголовок недействителен. Отдельно от этого гарантируется передача лишь 512 символов объединённого заголовка, а при урезании первыми отбрасываются записи длиннее 128 символов. Всё, что обязано пережить длинную цепочку вызовов, в tracestate не место.
- Никогда не записывайте trace ID как число JavaScript
- И 128-битный trace ID, и даже 64-битный идентификатор Datadog выходят за Number.MAX_SAFE_INTEGER. Держите их строками и переводите через BigInt, когда нужна арифметика, иначе последние цифры испортятся незаметно.
Часто задаваемые вопросы о декодере traceparent
Что такое заголовок traceparent?
Что означает traceparent trace-flags 00?
Чем различаются trace-flags 01, 02 и 03?
Почему мой trace ID состоит из одних нулей?
Как перевести trace ID из W3C в trace ID для Datadog?
Содержит ли traceparent метку времени?
Отправляется ли куда-нибудь заголовок, который я сюда вставляю?
Работает ли декодер офлайн?
Похожие инструменты
Все инструменты →Генератор и конструктор curl-команд
Веб и API
Создавайте curl-команды прямо в браузере: метод, заголовки, авторизация, тело — готовая команда мгновенно. Пресеты для Bearer, POST JSON, загрузки файлов. Бесплатно, приватно, без регистрации.
htpasswd Генератор — bcrypt, Apache MD5 (apr1) и Basic Auth
Веб и API
Генерируйте записи htpasswd с bcrypt, Apache MD5 (apr1), SHA-1 и другими алгоритмами. Получайте готовые конфиги для Apache, nginx и Docker. 100% в браузере — без загрузки данных.
Генератор Open Graph и мета-тегов
Веб и API
Создавайте мета-теги Open Graph, Twitter Card и SEO с живым предпросмотром в Google, Facebook и X. 100% бесплатно, в браузере, без регистрации — просто скопируйте код.
Тестер nginx location — почему побеждает этот блок
Веб и API
Смотрите, какой блок location в nginx победит — и почему проиграли все остальные. Бесплатный тестер совпадений для =, ^~, ~ и ~*, целиком в вашем браузере.
Инструмент расшифровки AES — совместим с OpenSSL и CryptoJS
Безопасность
Расшифровывайте AES онлайн — GCM/CBC/CTR, парольная фраза или необработанный ключ, автоматическое определение формата OpenSSL и CryptoJS «U2FsdGVkX1». Работает на 100% в браузере, ключи никогда не покидают страницу.
Инструмент шифрования AES — GCM, CBC и CTR
Безопасность
Бесплатное онлайн-шифрование AES — AES-128/192/256, GCM/CBC/CTR, парольная фраза (PBKDF2) или необработанный ключ. Работает на 100% в браузере, ничего не загружается на сервер.