traceparent 디코더 — W3C Trace Context
16진수 세기는 그만. 무료 온라인 traceparent 디코더 — 브라우저에서 실행, 업로드 없음. trace ID·span ID·trace-flags 8비트·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 |
이 비트들은 비트 AND로 읽으십시오. 바이트 전체를 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은 trace ID의 하위 64비트를 10진 문자열로, 상위 64비트를 태그의 16진으로 나릅니다. 128비트 전체를 10진으로 넘기는 것이 로그의 trace ID가 UI에서 아무것도 찾지 못하는 대표적인 이유입니다.
X-Ray ID에는 32비트 타임스탬프가 박혀 있지만, W3C trace ID는 타임스탬프를 전혀 담지 않습니다. 아래 날짜는 그 식별자가 실제로 X-Ray에서 나온 경우에만 의미가 있습니다.
| # | 키 | 값 | 상태 |
|---|---|---|---|
| 1 | rojo | 00f067aa0ba902b7 | OK |
| 2 | congo | t61rcWkgMzE | OK |
traceparent 형식: 필드 해부
| 필드 | 16진 자릿수 | 바이트 | 의미 | 무효한 값 |
|---|---|---|---|---|
| version | 2 | 1 | 형식 버전. 오늘날 언제나 00이며 ff는 금지입니다. | ff |
| trace-id | 32 | 16 | 추적 전체를 끝에서 끝까지 식별합니다. | 전부 0 |
| parent-id | 16 | 8 | 요청이 아니라 호출하는 span을 식별합니다. | 전부 0 |
| trace-flags | 2 | 1 | 8비트 필드 — 불리언이 아니라 비트 단위로 읽으십시오. | — |
trace-flags 값: 00, 01, 02, 03 해설
| 16진 | 2진 | 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: trace ID의 오른쪽 7바이트가 균일한 난수입니다.
bit 2-7 — 예약됨. 수신 시 무시하고 송신 시 지워야 합니다.
W3C Trace Context 권고안과 Level 2 후보 권고안을 직접 참조해 구현했으며, 명세가 명시한 유효·무효 형태 전부를 파서 단위 테스트로 덮었습니다.
traceparent 헤더란?
traceparent는 분산 추적을 한 서비스에서 다음 서비스로 실어 나르는 HTTP 헤더입니다. 표준화되기 전에는 추적 벤더마다 자기 헤더로 컨텍스트를 전파했기 때문에, 시스템을 넘나드는 요청은 경계에서 정체를 잃었습니다. W3C Trace Context 명세는 일부러 작게 설계한 단일 형식으로 이 문제를 해결했습니다. version-trace-id-parent-id-trace-flags, 하이픈으로 이은 네 개의 16진 필드이며 현재 버전 기준 전체 55자입니다.
각 필드는 한 가지 일만 합니다. version은 오늘날 언제나 00이고 ff는 아예 금지됩니다. trace-id는 요청 전체를 끝에서 끝까지 식별하는 16바이트로, 모든 홉에서 그대로 유지됩니다. parent-id는 바로 앞 호출자의 span을 식별하는 8바이트이므로 trace-id와 달리 홉마다 바뀝니다. 혼란이 몰리는 곳은 trace-flags 바이트입니다. 01이 압도적으로 흔하다 보니 불리언처럼 보이지만 실제로는 8개의 비트입니다. 비트 0이 sampled입니다. 비트 1은 Trace Context Level 2에서 추가된 random-trace-id로, trace ID의 오른쪽 7바이트가 균일한 난수임을 선언해 하위 시스템이 그 값을 기준으로 샘플링하거나 샤딩할 수 있게 합니다. 나머지 6비트는 예약되어 있으며, 바로 그래서 이 필드는 같은지 비교하는 대신 비트 AND로 읽어야 합니다.
짝이 되는 헤더인 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를 8비트로 읽기
플래그 바이트를 16진 마스크와 함께 여덟 자리 전부로 펼칩니다. 비트 0은 sampled, 비트 1은 Level 2의 random-trace-id 플래그이며, 예약 비트도 조용히 버리지 않고 보여 줍니다.
Datadog·X-Ray·B3 변환
하위 64비트를 10진으로 표현한 Datadog trace ID, 함께 전달되는 상위 64비트 태그, X-Ray의 1-{8}-{24} 형태, 그리고 B3의 단일 헤더와 다중 헤더 배치까지 — 모두 BigInt로 계산해 넘침이 없습니다.
판정이 아니라 진단
전부 0인 trace ID는 추적이 초기화되지 않은 상태로, 꺼진 sampled 비트는 상위에서 내린 결정으로 설명합니다. 지금 보는 것이 둘 중 무엇인지 가려내는 일이 대개 디버깅의 전부입니다.
32개 상한이 붙은 tracestate
멤버마다 키와 값을 검증해 나열하고 명세의 상한 대비 개수를 셉니다 — 벤더 데이터가 몇 홉 아래에서 사라지는 이유가 되는 바로 그 상한입니다.
브라우저 밖으로 나가지 않음
해석은 의존성도 네트워크 호출도 없이 평범한 문자열 처리와 BigInt 연산만으로 이뤄지며, 빌드마다 도는 자동 계약 테스트로 검증됩니다. 링크 복사는 전송되지 않는 URL 프래그먼트를 사용합니다.
traceparent 해석 예시
명세에 실린 예제를 그대로 해석하기
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
version 00 · trace-id 4bf92f3577b34da6a3ce929d0e0e4736 · parent-id 00f067aa0ba902b7 · trace-flags 01 (sampled)
하이픈으로 구분된 네 개 필드이며, version 00 기준 전체 길이는 55자입니다. trace-id는 요청이 거쳐 가는 모든 서비스를 관통해 요청 전체를 식별합니다. 흔히 span ID라고 부르는 parent-id는 바로 앞 호출자만 식별하므로, trace-id와 달리 홉마다 바뀝니다. 끝의 01은 불리언이 아니라 온전한 1바이트입니다. 비트 0이 켜져 있으므로 호출자가 이 추적을 기록했습니다.
trace-flags 00 — 호출자가 기록하지 않기로 결정했습니다
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
유효한 헤더 · sampled 비트 꺼짐
이 헤더는 완벽하게 유효하며, 바로 그 점이 핵심입니다. sampled 비트가 내려간 것은 상위에서 내려온 지시이지 내 서비스의 결함이 아닙니다. 나를 호출한 쪽이 자기 샘플러를 평가한 뒤 기록하지 않기로 선택한 것입니다. 이 상황에서 내 설정을 뒤지며 사라진 span을 찾으면 몇 시간이 그대로 날아갑니다. 던져야 할 질문은 어느 서비스가 부모 span을 보내면서 이 추적을 샘플링하지 않기로 결정했는가입니다.
전부 0인 trace ID는 추적이 시작조차 안 됐다는 뜻입니다
00-00000000000000000000000000000000-00f067aa0ba902b7-01
무효 — trace-id가 전부 0
명세는 전부 0인 trace-id를 무효로 규정하고 traceparent 전체를 무시하도록 요구합니다. 실무에서 이 값이 무엇을 알리는지 알아둘 필요가 있습니다. ‘아직 데이터가 없는 추적’이 아니라, 초기화되지 않은 SDK이거나 자리표시자 헤더를 주입하는 미들웨어입니다. 전부 0인 parent-id에도 같은 규칙이 적용됩니다.
같은 trace ID를 Datadog 형식으로
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
x-datadog-trace-id 11803532876627986230 · _dd.p.tid 4bf92f3577b34da6
Datadog은 128비트 trace ID의 하위 64비트를 10진 문자열로 나르고, 상위 64비트는 별도 태그에 16진 그대로 담습니다. 128비트 전체를 10진으로 넘기면 어디에도 걸리지 않는 숫자가 나오는데, 각 트레이서 이슈 트래커에 이 변환 질문이 반복해서 올라오는 이유가 정확히 이것입니다. 여기서 하위 절반은 a3ce929d0e0e4736이며, 64비트는 JavaScript number가 담을 수 있는 범위를 넘기 때문에 이 페이지는 BigInt로 계산합니다.
traceparent 디코더 사용법
- 1
traceparent 헤더 붙여넣기
원본 헤더 값을 그대로 넣으십시오. 예: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01. 입력과 동시에 해석되므로 누를 버튼이 없습니다.
- 2
네 필드를 따로 읽기
version, trace-id, parent-id, trace-flags가 각자의 행으로 나뉘고 행마다 복사 버튼이 붙습니다. 32자를 손으로 드래그하지 않고도 trace ID만 쿼리로 가져갈 수 있습니다.
- 3
플래그를 비트 단위로 확인하기
trace-flags 바이트를 마스크와 함께 8비트 전부로 펼칩니다. sampled와 Level 2의 random-trace-id 플래그가 두 글자 값 속에 묻히지 않고 각각 드러납니다.
- 4
사용하는 백엔드 형식으로 변환하기
Datadog, AWS X-Ray, B3의 두 형태가 아래에 생성됩니다. Datadog이 기대하는 하위 64비트 10진 trace ID와 함께 전달되는 상위 64비트 태그도 포함됩니다.
- 5
tracestate를 더하고 결과 공유하기
tracestate 헤더를 붙여넣으면 멤버가 개별 검증과 함께 나열되고 32개 상한 대비 개수가 표시됩니다. 그다음 링크 복사로 현재 상태를 그대로 URL에 담아 티켓에 붙일 수 있습니다.
traceparent에서 흔한 실수
플래그 바이트 전체를 01과 비교하기
8비트 필드를 열거형처럼 다루는 것입니다. 샘플링되었고 Level 2의 random-trace-id 플래그까지 있는 추적은 flags가 03이며, 동등 비교는 이를 샘플링되지 않았다고 보고합니다.
if (traceFlags === 0x01) { record(); } if (traceFlags & 0x01) { record(); } 128비트 전체를 하나의 10진수로 변환하기
Datadog은 하위 64비트를 10진으로, 상위 64비트를 별도 태그의 16진으로 기대합니다. 전체 값을 하나의 10진수로 넘기면 어디에도 걸리지 않는 식별자가 나옵니다.
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 */ } 대문자 16진 내보내기
문법이 인정하는 것은 소문자뿐입니다. 대문자 trace ID는 값 자체는 맞지만 규격을 따르는 수신 측에서 거부되므로, 눈으로 잡아내기가 유난히 성가신 버그가 됩니다.
traceparent: 00-4BF92F3577B34DA6A3CE929D0E0E4736-00F067AA0BA902B7-01
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
traceparent 디코더로 할 수 있는 일
- 추적에 span이 없는 이유 파악하기
- 들어온 헤더를 붙여넣고 sampled 비트를 읽으십시오. 꺼져 있다면 그 추적은 애초에 기록될 예정이 없었고, 답은 내 계측이 아니라 호출자 쪽에 있습니다. 이 구분 하나로 내 샘플러 설정을 뒤지는 시간을 크게 아낄 수 있습니다.
- 백엔드가 찾지 못하는 추적 찾아내기
- 애플리케이션 로그에서 복사한 trace ID가 Datadog에서 아무것도 반환하지 않는다면 대개 형식이 원인입니다. 여기서 변환하면 API가 기대하는 하위 64비트 10진 식별자와 함께 붙여야 하는 상위 64비트 태그를 확인할 수 있습니다.
- 게이트웨이가 주입하는 헤더 검증하기
- 프록시와 서비스 메시는 유입 시점에 추적 컨텍스트를 생성합니다. 실제로 도착한 값을 붙여넣어 길이, 소문자 16진, 0이 아닌 식별자를 먼저 확인한 뒤에 하위 탓이라고 판단하십시오.
- 운영 추적을 손으로 재현하기
- 실제 요청의 헤더를 가져와 스테이징 엔드포인트에 재생하면 같은 추적을 따라갈 수 있습니다. 요청은 curl 명령 빌더로 조립하고 헤더를 그대로 붙여 넣으십시오.
- 팀에 trace context 설명하기
- 이 페이지의 필드 해부 표와 trace-flags 표는 그대로 가리키며 설명할 수 있는 정적 참고 자료이고, 프리셋 칩은 누군가 서비스를 망가뜨리지 않고도 각 실패 유형을 보여 줍니다.
W3C Trace Context 검증기의 동작 방식
- 네 필드 문법
- version "-" trace-id "-" parent-id "-" trace-flags이며 전부 소문자 16진입니다. version은 2자리, trace-id는 32자리, parent-id는 16자리, trace-flags는 2자리로, 16진 52자리에 하이픈 3개를 더해 version 00 기준 정확히 55자입니다. 값이 맞아 보여도 대문자 16진은 헤더를 무효로 만듭니다. 또한 전부 0인 trace-id와 전부 0인 parent-id는 비어 있는 것이 아니라 명시적으로 무효입니다.
- trace-flags는 비트 필드
- 비트 0(마스크 0x01)은 sampled로, 켜져 있으면 호출자가 추적 데이터를 기록했을 수 있다는 뜻입니다. Level 2에서 도입된 비트 1(마스크 0x02)은 random-trace-id로, 켜져 있으면 trace-id의 최소한 오른쪽 7바이트가 균일 분포의 난수로 선택되었어야 하며, 덕분에 하위 시스템이 그 값으로 샘플링하거나 샤딩할 수 있습니다. 비트 2부터 7까지는 예약이며 수신 시 무시하고 송신 시 지워야 합니다. 예약 비트가 있을 수 있으므로 이 필드는 비트 AND로 검사해야 합니다. 0x01과의 동등 비교는 예약 비트까지 켜진 샘플링된 추적을 잘못 보고합니다.
- 미래 버전과의 전방 호환성
- version은 오늘 00이고 ff는 금지지만, 나머지를 전부 거부하는 파서는 틀렸습니다. 명세는 버전이 더 높고 헤더 길이가 알려진 형식 이상일 때, 추적을 새로 시작하는 대신 해석을 시도해 알아볼 수 있는 필드를 읽고 남는 뒤쪽 데이터를 허용하도록 수신 측에 요구합니다. 이 디코더도 그 규칙을 따릅니다. 미래 버전은 해석에 성공하며 오류가 아니라 경고로 표시됩니다.
- 운영에서 발목을 잡는 tracestate 제한
- 리스트 멤버는 최대 32개입니다. 이는 문법상의 엄격한 경계여서, 이를 넘기면 헤더 자체가 무효가 되고 수신 측은 그것을 버립니다. 각 키는 최대 256자에 소문자나 숫자로 시작하며, Level 2부터 @는 테넌트 구분자가 아니라 평범한 키 문자입니다. 각 값은 1자에서 256자 사이의 출력 가능한 ASCII이고, 쉼표나 등호를 담을 수 없으며 비어 있어서도 안 됩니다. 키 중복은 무효이지만 빈 리스트 멤버는 명세가 명시적으로 허용합니다. 중간 노드가 항목을 지우고 남긴 끝의 쉼표도 여전히 유효한 헤더입니다. 이와 별개로 벤더는 합쳐진 헤더를 최소 512자까지 전파해야 하며, 그 예산에 맞추려고 잘라 낼 때는 128자가 넘는 항목부터 버려야 합니다. 장황한 벤더의 데이터가 간결한 벤더의 것보다 먼저 사라지는 이유가 바로 이것입니다.
Trace Context 모범 사례
- 플래그는 비트 AND로 검사하기
- flags == 0x01이 아니라 flags & 0x01로 쓰십시오. 여덟 비트 중 여섯은 앞으로를 위해 예약되어 있고, 그중 하나라도 실제로 나타나는 순간부터 동등 비교는 샘플링된 추적을 잘못 보고하기 시작합니다.
- 전부 0인 ID는 파이프라인 고장으로 취급하기
- 너그럽게 넘길 빈 값이 아닙니다. 헤더를 거부하고, 트레이서 초기화에 실패했거나 자리표시자를 주입하고 있는 구성 요소를 찾아 나서십시오.
- sampled 비트가 꺼져 있으면 상위를 보기
- 부모 기반 샘플러는 호출자의 결정을 전파합니다. 추적이 비어 있다면 내 설정을 감사하기 전에, 샘플링을 끈 부모 span을 보내는 서비스가 어디인지부터 특정하십시오.
- tracestate는 짧게 유지하기
- 32개 상한은 문법상의 엄격한 경계입니다. 넘기는 순간 헤더가 무효가 됩니다. 이와 별개로 합쳐진 헤더는 512자까지만 전파가 보장되고, 잘라 낼 때는 128자가 넘는 항목부터 버려집니다. 긴 호출 사슬에서 살아남아야 하는 데이터라면 애초에 tracestate에 둘 것이 아닙니다.
- trace ID를 JavaScript number로 로그에 남기지 않기
- 128비트 trace ID는 물론 64비트 Datadog 식별자조차 Number.MAX_SAFE_INTEGER를 넘습니다. 문자열로 유지하고 연산이 필요할 때만 BigInt로 변환하십시오. 그러지 않으면 끝자리가 조용히 망가집니다.
traceparent 디코더 자주 묻는 질문
traceparent 헤더란 무엇인가요?
traceparent의 trace-flags 00은 무슨 뜻인가요?
trace-flags의 01, 02, 03은 어떻게 다른가요?
trace ID가 전부 0인 이유는 무엇인가요?
W3C trace ID를 Datadog trace ID로 어떻게 변환하나요?
traceparent에 타임스탬프가 들어 있나요?
여기에 붙여넣은 헤더가 어딘가로 올라가나요?
이 디코더는 오프라인에서도 동작하나요?
관련 도구
모든 도구 보기 →cURL 명령어 생성기 & 빌더
웹 & API
온라인 curl 명령어 생성기. 메서드·헤더·인증·바디를 설정하면 즉시 복사 가능한 명령어가 생성됩니다. Bearer·POST JSON·파일 업로드 프리셋. 무료, 서버 전송 없음.
htpasswd 생성기 — bcrypt, Apache MD5 (apr1) & Basic Auth
웹 & API
bcrypt, Apache MD5 (apr1), SHA-1 등으로 htpasswd 항목을 생성하는 웹 도구. Apache, nginx, Docker 설정 스니펫 포함. 100% 브라우저에서 처리 — 업로드 없음.
Open Graph 메타 태그 생성기
웹 & API
Open Graph, Twitter Card, SEO 메타 태그를 생성하고 Google·Facebook·X 실시간 미리보기로 확인하세요. 100% 무료 웹 도구, 가입 없이 코드를 복사·붙여넣기.
nginx location 테스터 — 그 블록이 이기는 이유
웹 & API
어떤 nginx location 블록이 이기고 나머지는 왜 졌는지 보여줍니다. =, ^~, ~, ~* 매칭을 브라우저 안에서 처리하는 무료 온라인 테스터입니다.
AES 복호화 도구 — OpenSSL·CryptoJS 호환
보안 도구
온라인 AES 복호화 — GCM/CBC/CTR, 암호 문구 또는 원시 키, OpenSSL·CryptoJS "U2FsdGVkX1" 형식 자동 인식. 브라우저에서만 실행되며 키는 유출되지 않습니다.
AES 암호화 도구 — GCM, CBC, CTR 모드
보안 도구
무료 온라인 AES 암호화 도구 — AES-128/192/256, GCM/CBC/CTR, 암호 문구(PBKDF2) 또는 원시 키. 브라우저에서만 실행되고 서버 업로드는 없습니다.