Spring version 3.x 와 2.x 간의 traceId 연동
기존에는 Spring 2.x버전만 사용하고 있었기에 전부 Spring Cloud Sleuth 를 사용했고 이를 이용하면 별 문제없이 traceId가 로그에 노출됐습니다.
이번에 신규 프로젝트가 Spring 3.x를 사용했고, 3.x버전에서 2.x의 rpc를 호출하는 과정에 traceId 가 제대로 이어지지않아서 왜 그런지를 정리하고자 합니다.
Spring 2.x버전의 경우 Spring Cloud Sleuth를 사용하고있고 b3-propagation format을 사용하고있습니다.
Spring 3.x버전의 경우 Micrometer Tracing을 사용하며 dependency는 아래와 같습니다.
그리고 이번 버전과는 다르게 w3c trace context format을 사용합니다.
// trace
implementation("io.micrometer:micrometer-tracing-bridge-brave")
이 두개의 차이로 인하여 통신과정에 서로 다른 방식으로 traceId 를 해석했기에, 정상적으로 traceId가 전파되지 않았습니다.
우선 이를해결하는법 부터 정리하고 아래에서 좀더 자세하게 살펴봅니다.
우선 첫번째 방법은 client 입장의 서비스에서 b3 방식으로 강제회하는 방법입니다.
이 방법은 client를 강제로 b3로 보낼 수 있는 방법이나, 저는 아래의 방법을 택했습니다.
management:
tracing:
propagation:
type: b3
brave:
span-joining-supported: true // 요건은 조금더 확인중..
두번째 방식은 serveer 입장의 서비스에서 b3,w3c를 둘다 지원하는 방법입니다.
이렇게 하면 Spring3.x 에서 w3c를 보내더라도 2.x 버전의 서버에서 올바르게 traceId 가 이어집니다.
가이드 문서에 어떻게 바꾸면되는지 친절하게 작성이 되어있습니다.
spring:
sleuth:
trace-id128: true
propagation:
type: w3c, b3
supports-join: false
자 그러면 두번째 방식을 기준으로 rpc호출과정에 어떻게 traceId를 이어나가는지 확인해보겠습니다.
우선 rpc에서는 BraveGrpcAutoConfiguration 해당 클레스를 통해서 아래와 같이 traceId관련 클레스를 bean으로 등록하고 있습니다.
그 결과 rpc가 호출되는 과정에 TracingServerInterceptor 가 동작하면서 traceId를 헤더에서 파싱해오게 됩니다.
우선 rpc과정에 간략한 interceptor를 하나 작성하여 관련 rpc헤더를 호출해보았습니다. 3.x에서 2.x을 호출했을때 찍히는 헤더는 다음과 같습니다.
traceparent으로 들어오는 해당 값이 traceId의 메인 값입니다.
00-6655cf0019149df50d7f9c2358316b20-ff35260ba3020b8f-00
각각의 값을 설명해주신 페이지도 첨부해봅니다.
이제 위에서 작성했던 두번째 방법을 적용하게되면 w3c방식의 헤더를 파싱목록에 포함하게되며 W3CPropagation 클레스가 위 헤더를 적절하게 변환하여 traceId를 이어줍니다.
만약 위에서 w3c를 받는 설정을 하지않았다면, null로 인지 하고 새로운 traceId가 노출되어 로그상에서는 달라리게 됩니다.