- 어떤 작업이 요청을 시작했는지
- 요청이 어디에서 시간을 썼는지
- 어떤 자식 작업이 오류를 반환했는지
- 어떤 로그, 이슈, 액션, 메트릭이 같은 트레이스 ID를 가졌는지
- 어떤 서비스, 환경, 릴리스가 각 스팬을 보냈는지
트레이스와 스팬 필드
루트 스팬은 트레이스를 시작하며 부모가 없습니다. 자식 스팬은 같은 트레이스 ID, 고유한 스팬 ID, 부모 ID를 가집니다. 작업은 이 ID로만 연결됩니다. 타임스탬프만으로는 연결되지 않습니다. LogBrew는
status가 error인 스팬만 오류 스팬으로 셉니다.
여러 서비스를 거치는 요청
- 웹 서비스가 체크아웃 라우트의 서버 스팬을 시작합니다.
- 결제 클라이언트가 아웃바운드 HTTP 요청의 자식 스팬을 만듭니다.
- 결제 서비스가 자체 서버 스팬으로 트레이스를 이어 갑니다.
- 데이터베이스 헬퍼가 쓰기 작업의 자식 스팬을 기록합니다.
- 앱이 활성 결제 스팬 안에서 안전한 오류 로그를 보냅니다.
컨텍스트 전파
LogBrew SDK는 W3C 트레이스 컨텍스트를 사용합니다. 예를 들어 Node.js SDK는 들어온traceparent 헤더가 유효하면 새 요청 스팬으로 그 트레이스를 이어 갑니다. 헤더가 없거나 유효하지 않으면 새 루트를 시작합니다. 그 요청 범위 안에서 수집된 로그, 이슈, 액션, 메트릭은 요청의 트레이스를 가집니다.
아웃바운드 계측은 tracePropagationTargets처럼 직접 설정한 대상에만 traceparent 헤더를 씁니다. 트레이스 컨텍스트는 신뢰할 수 있고 계측된 서비스에만 보내세요. 트레이스 ID는 작업을 서로 연관 짓습니다. 인증 수단이 아닙니다.
큐 메시지도 트레이스 컨텍스트를 담을 수 있습니다. Node.js에서는 프로듀서 작업에서 createLogBrewQueueTraceHeaders()를 호출해 메시지에 traceparent 헤더를 추가하세요. 컨슈머에서는 그 헤더를 queueOperationWithLogBrewSpan()에 traceparent로 전달하세요. JavaScript 큐 트레이싱을 참고하세요.
Node.js와 Python의 요청 연동과 아웃바운드 연동은 요청 본문, 응답 본문, 쿼리 문자열, 임의 헤더, 원시 traceparent 값을 스팬에 기록하지 않습니다. 스팬 이름은 구체적인 URL이 아니라 라우트 템플릿을 따라 지으세요. 사용하는 런타임의 연동 기능은 SDK 연동 문서를 참고하세요.
수집 스팬
LogBrew는 새 로그, 이슈, 액션, 메트릭을 모두 트레이스 ID와 함께 저장합니다. 시그널이 같은 전송에 포함된 스팬을 가리키지 않으면, LogBrew가 그 시그널에 수집 스팬 1개를 추가합니다.
이후 시그널의
span_id는 해당 수집 스팬을 가리킵니다. 시그널에 트레이스 컨텍스트가 없었다면 LogBrew가 새 트레이스 ID를 만듭니다. 이 트레이스는 LogBrew가 시그널을 저장했다는 사실만 보여 줍니다. 요청 경로를 보여 주지는 않습니다. 한 트레이스에 있는 수집 스팬을 요청 1건으로 해석하지 마세요.
수집 스팬도 span_count와 error_span_count에 포함됩니다. 그래서 애플리케이션 작업이 하나도 실패하지 않은 트레이스가 오류 로그 때문에 --status error로 선택될 수 있습니다. 결론을 내리기 전에 각 오류 스팬의 operation을 확인하세요.
트레이스 읽기
로그, 이슈, 트레이스 목록에서 가져온 정확한 트레이스 ID를 사용하세요.--status error는 오류 스팬이 1개 이상 있는 트레이스를 선택합니다. --status ok는 오류 스팬이 없는 트레이스를 선택합니다. --min-duration-ms 500은 500밀리초 이상 실행된 트레이스를 선택합니다.
먼저 루트 스팬의 소요 시간을 확인하세요. 그다음 가장 오래 걸린 자식 스팬과 오류 상태를 살펴보세요. 스테이징 트레이스를 프로덕션의 근거로 쓰지 않도록 프로젝트, 서비스, 환경, 릴리스를 계속 확인하세요.
트레이스 1개는 실행 1회를 보여 줄 뿐 성능 기준선이 아닙니다. 성능 개선을 제안하기 전에 여러 트레이스를 관련 메트릭 추세와 비교하세요.
트레이스 요약
GET /api/telemetry/traces/{trace_id}/summary는 스팬 속성 없이 요약을 반환합니다.
root_span.parent_span_id에 값이 있으면 실제 루트 스팬은 트레이스에 없습니다. 이때 root_span을 요청의 시작으로 해석하지 마세요.
트레이스 분석하기
logbrew explain trace는 트레이스 조사 결과를 반환합니다.
analysis.causality는 evidence_only입니다. 이 분석은 근본 원인을 증명하지 않습니다. CLI는 응답 버전 3을 요청합니다. 이 버전에서는 관련 이슈, 액션, 메트릭마다 정확한 span_id도 들어 있습니다.
스팬 1개를 부모, 자식, 서비스 경계와 함께 살펴보려면 다음을 실행하세요.
topology.parent_chain_status는 부모 체인이 완전한지 알려 줍니다.
트레이스 컨텍스트 누락
모든 이벤트에 요청 트레이스가 있는 것은 아닙니다. 트레이스 상태를 확인하세요.not_linked는 오류가 아닙니다. available 상태의 트레이스로도 이벤트에 요청 컨텍스트가 없었다는 사실을 알 수 있습니다. 이벤트의 수집 스팬에 parent_span_id가 없으면, 앱이 이벤트를 수집할 때 활성 스팬이 없었던 것입니다. 요청 범위 밖의 백그라운드 작업에서 이런 결과가 자주 나옵니다. 빠진 관계를 찾으려면 다음 순서로 확인하세요.
- 이벤트의 프로젝트, 서비스, 환경, 릴리스, 시각을 확인하세요.
- 해당 작업이 계측된 요청이나 작업 안에서 실행되었는지 확인하세요.
- 클라이언트 연동과 서버 연동이 그 경계를 넘어 컨텍스트를 전파하는지 확인하세요.
- 계측을 고친 다음 새 이벤트를 수집해 읽어 보세요.
프로젝트 1개의 트레이싱 계획 세우기
체크아웃처럼 중요한 요청이나 잡 1개부터 시작하세요. 경계를 하나씩 계측하세요.- 들어오는 요청이나 백그라운드 작업에 대한 스팬을 만드세요.
- 중요한 아웃바운드 호출에 자식 스팬을 추가하세요.
- 신뢰할 수 있는 서비스 경계를 넘어 W3C 트레이스 컨텍스트를 이어 가세요.
- 활성 스팬 안에서 안전한 로그를 보내세요.
- 그 로그를 읽고 트레이스 ID를 연 다음, 루트, 자식, 서비스, 환경, 릴리스, 상태, 소요 시간을 확인하세요.
logbrew traces --project "<project_id>" --pagination cursor --json을 실행하세요. naming_quality 객체는 그 페이지에서 루트 이름이 일반적인 트레이스(generic_name_traces)와 일치하는 라우트가 없는 트레이스(unmatched_route_traces)의 수를 셉니다. 이름을 손봐야 하면 naming_quality.next_action.code가 improve_trace_naming입니다.