로그로 원인 찾기 · 상관 id 로 요청 하나를 잇기 · 실습
주문 하나가 사라졌는데 서비스는 다섯 개였다
목표
서비스 다섯 개의 로그에서 주문 하나의 경로를 처음부터 끝까지 잇습니다. W3C traceparent 를 네 칸으로 갈라 무효한 값을 격리하고, 한 trace-id 의 줄을 시간순으로 세우고, parent-id 로 구간 나무를 만들고, 구간별 소요 시간을 구하고, 헤더가 끊긴 자리를 업무 키로 이은 뒤, sampled 플래그를 마스크로 읽습니다.
왜 중요한가
고객은 "주문 하나가 사라졌다" 고 말하는데 서비스는 다섯 개입니다. 시각으로 짐작하면 초당 수십 건의 요청 가운데 어느 것이 그 주문인지 고를 근거가 없습니다. 상관 id 는 그 자리를 메우지만, 현장에서 실제로 부딪히는 문제는 id 가 없는 것이 아니라 중간 한 곳에서 끊기는 것입니다. 끊긴 자리를 찾아내고, 그 앞뒤를 업무 키로 다시 이어 증명하는 일까지가 조사입니다. 그 증명이 다음 배포에서 헤더를 전달하게 만드는 근거가 됩니다.
단계
1. /root/trace/gen_trace.py 를 만들어 실행해 /root/trace/raw/ 아래 다섯 서비스의 로그를 만드세요.
2. /root/trace/parsed.ndjson 과 /root/trace/badtp.ndjson — 모든 traceparent 를 네 칸으로 가르고, 규격에 맞지 않는 값은 이유와 함께 격리하세요.
3. /root/trace/one_trace.ndjson — 주문 ORD-2026-4117 의 trace-id 를 찾아 그 추적의 모든 줄을 시간순으로 세우세요.
4. /root/trace/tree.ndjson — parent-id 로 부모-자식 관계를 세워 구간 나무를 만드세요.
5. /root/trace/elapsed.json — 구간별 소요 시간과 자기 시간을 구하세요.
6. /root/trace/bridge.ndjson 과 /root/trace/gap.json — 헤더가 끊긴 서비스를 찾아 그 앞뒤를 주문번호로 이으세요.
7. /root/trace/sampled.json — sampled 플래그를 마스크로 읽어 기록된 추적과 안 된 추적을 가르세요.
8. /root/trace/trace_report.md — 조사 결과를 보고서로 남기세요.
참고
- traceparent 는
버전-trace-id-parent-id-trace-flags네 칸을 하이픈으로 이은 고정 길이 값입니다. 길이는 차례대로 2 · 32 · 16 · 2 자이고, 문자는 소문자 16진만 허용됩니다. - 무효값 검사는 이 순서로 합니다: 칸 수와 길이(bad_shape) → 소문자 16진(non_lowercase_hex) → 버전이 현재 버전 00 인가(bad_version — 이 실습은 00 만 받습니다. 규격은 ff 를 무효로 못박습니다) → trace-id 가 전부 0 인가(zero_trace_id) → parent-id 가 전부 0 인가(zero_parent_id).
- 내가 받은 헤더의 parent-id 는 나를 부른 쪽의 구간 id 이고, 내가 보내는 헤더의 parent-id 는 내 구간 id 입니다. 로그의 traceparent_in 과 traceparent_out 이 각각 그 둘입니다.
- trace-flags 는 8비트 필드입니다.
01과 같은지 비교하지 말고 최하위 비트를 마스크하세요 —09도03도 sampled 입니다. - 이 실습의 산출물은 전부
/root/trace/아래에 모읍니다. 세션이 끝나면 사라지므로 중요한 것은 화면에 남겨 두세요. - 흔한 실수: 무효한 traceparent 를 조용히 건너뛰기, 자기 시간을 구하지 않고 소요 시간만 보기, 헤더가 없는 서비스를 "로그가 없다" 로 넘기기, sampled 를 문자열 비교로 세기.
단계 8개
- 다섯 서비스의 로그를 손에 쥐기
- traceparent 를 네 칸으로 가르기
- 그 주문의 추적을 시간순으로 세우기
- parent-id 로 구간 나무 세우기
- 시간이 어디서 갔는지 구간별로 재기
- 끊긴 자리를 찾아 주문번호로 잇기
- sampled 플래그를 마스크로 읽기
- 조사 결과를 보고서로 남기기