목차
로그는 사건을, 메트릭은 전체를 본다. 그런데 “이 느린 요청이 여러 서비스 중 어디서 시간을 썼나”는 둘 다 못 짚는다. 그 빈칸을 메우는 게 트레이싱이다.
로그도 메트릭도 못 답하는 것
주문 하나가 게이트웨이 → 인증 → 재고 → 결제를 지난다(마이크로서비스). “이 요청이 400ms 걸렸다”는 메트릭이 알려준다. 그런데 그 400ms를 어느 서비스가 썼나?
- 메트릭은 “결제 서비스 p99가 높다”까진 알아도, 한 요청 안에서 결제가 범인인지 재고가 범인인지 뭉갠다.
- 로그는 서비스마다 따로 찍혀서, 상관ID로 모아도 각 구간이 얼마나 걸렸는지를 시간축으로 세우기 어렵다.
마이크로서비스 글이 “무슨 일이 있었는지 보기 어려워진다”고 미뤄둔 대가가 정확히 이것이다. 그 대가를 갚는 도구가 분산 트레이싱이다.
스팬: 한 구간의 기록
트레이싱의 기본 단위는 **스팬(span)**이다. 스팬 하나는 작업 하나의 기록이다 - 언제 시작해 언제 끝났고, 무슨 일이었는지.
스팬: "결제 승인 호출"
시작 100ms, 끝 380ms (걸린 시간 280ms)
service=payment, status=ok“토큰 검증”, “재고 조회 쿼리”, “결제 API 호출” 하나하나가 각각 스팬이다. 로그 한 줄과 닮았지만 결정적 차이가 있다 - 스팬은 시작과 끝, 즉 걸린 시간을 담는다.
트레이스: 스팬을 잇는 한 요청
**트레이스(trace)**는 한 요청이 남긴 모든 스팬을 묶은 것이다. 스팬들은 부모-자식으로 이어진다 - 게이트웨이 스팬이 부모, 그 안에서 부른 인증·재고·결제 스팬이 자식.
한 트레이스는 곧 요청 하나의 전체 지도다. 어떤 서비스를 어떤 순서로 지났고 각 구간이 얼마였는지가 다 들어 있다. 이제 이 지도를 시간축에 눕히면 병목이 눈에 보인다.
폭포수로 어디서 느렸나 본다
스팬들을 시작 시각에 맞춰 시간축에 늘어놓으면 폭포수(waterfall) 모양이 된다. 막대 길이가 곧 걸린 시간이다.


한눈에 온다 - 결제 승인이 280ms로 유독 길다. 인증·재고는 짧게 끝났고, 전체 400ms의 대부분을 결제가 먹었다. 로그를 아무리 읽어도 안 나오던 “어디서”가, 막대 길이 하나로 드러난다. 트레이싱을 쓰는 이유가 바로 이 그림이다.
상관ID를 서비스 너머로 넘긴다
어떻게 흩어진 서비스의 스팬들이 하나의 트레이스로 묶일까. 요청 입구에서 만든 trace ID(로그 편의 상관ID)를, 다음 서비스를 부를 때 함께 넘기기 때문이다. 대개 HTTP 헤더에 실어 보낸다.
게이트웨이 --(헤더: trace_id=a1b2)--> 결제 서비스
결제 서비스도 같은 a1b2로 자기 스팬을 남긴다이렇게 ID를 경계 너머로 전달하는 걸 컨텍스트 전파(context propagation)라 한다. 로그 편의 상관ID가 한 프로세스 안에서 줄을 꿰었다면, 트레이싱은 그 ID를 서비스 사이로 넘겨 전체를 꿴다. 그래서 트레이싱은 “서비스 경계를 넘는 상관ID”라고 봐도 크게 틀리지 않는다.
전부는 못 담는다: 샘플링
모든 요청을 트레이스로 남기면 어떻게 될까. 초당 수만 요청이면 스팬이 폭발해 저장도 비용도 감당이 안 된다. 그래서 샘플링한다 - 일부만 골라 담는다.
- 비율 샘플링 - 100건에 1건처럼 정해진 비율만.
- 꼬리 샘플링 - 느리거나 실패한 요청을 우선 담는다(정상보다 사고가 궁금하니까).
관측이 공짜가 아니라던 첫 글의 예고가 여기서 구체가 된다 - 트레이스는 다 남길 수 없어 무엇을 남길지 고른다.
트레이스가 로그·메트릭을 잇는다
트레이스의 숨은 쓸모는 세 기둥을 잇는 것이다. 모든 로그·스팬에 같은 trace ID가 박혀 있으면,
- 메트릭에서 **“p99가 튀었다”**를 보고 → 그 시간대의 느린 트레이스를 열고 → 그 트레이스의 로그로 내려가 “왜”를 읽는다.
하나의 실(trace ID)로 세 신호를 꿰는 이 흐름이 관측의 완성형이다. 마지막 편에서 정면으로 다룬다.
실무에서: 자동 계측과 수동 계측
- 자동 계측 - 라이브러리가 HTTP 호출·DB 쿼리 같은 흔한 구간의 스팬을 알아서 만든다. 코드를 거의 안 건드린다.
- 수동 계측 - 비즈니스상 중요한 구간(“할인 계산”)은 직접 스팬을 연다.
- **OpenTelemetry**가 이 계측의 표준이다 - 한 규격으로 심으면 어느 트레이싱 백엔드로도 보낼 수 있다.
정리
- 트레이싱은 “이 요청이 어디서 느렸나”에 답한다 - 로그·메트릭이 못 짚는 자리다.
- 스팬은 걸린 시간을 담은 한 구간, 트레이스는 한 요청의 모든 스팬. 시간축에 눕히면 폭포수로 병목이 보인다.
- trace ID를 서비스 너머로 전파해 흩어진 스팬을 하나로 묶는다 - 경계를 넘는 상관ID다.
- 전부는 못 담아 샘플링하고, 같은 trace ID로 로그·메트릭까지 잇는다.
다음 글은 이 신호들을 보고 언제 사람을 부를지 - 헬스체크와 알림으로 간다.