로그 추적기 v2 개발
- v1의 문제점을 해결해보자.
- 요청을 한 번만 했으니 트랜잭션 ID가 동일해야 하는데 깊이가 변경될 때마다 새로운 트랜잭션 ID가 발급된다.
- 깊이가 다른데도 같은 깊이처럼 출력된다.
- 상태가 연동되지 못 하는 것은 당연히 이전 로그의 상태가 어떻게 되었는지 알 수 없기 때문이다.
- 가장 단순하게 처리하기 위해 로그의 상태 정보를 다음 로그에게 넘기는 방식으로 수정하면 된다.
- 로그의 상태 정보인 트랜잭션 ID와 깊이값은 TraceId 클래스에 포함되어 있다.
- 즉, TraceId를 다음 로그에 넘기면 된다.
- 파라미터 동기화 작업을 위해 기존의 TraceV1을 복사하여 TraceV2를 추가하자.
- 기존 TraceV1에서 메소드 하나만 추가되었다.
로그 추적기 v2 테스트
- TraceV2에서 단축키
Ctrl + Shift + T
를 실행해서 테스트를 생성하자.
- begin_end_level2 실행 로그
[cd110c7e] hello1
[cd110c7e] |–>hello2
[cd110c7e] |<–hello2 time=2m
[cd110c7e] hello1 time=11ms - begin_exception_level2 실행 로그
[040996e7] hello
[040996e7] |–>hello2
[040996e7] |<X-hello2 time=2ms ex=java.lang.IllegalStateException
[040996e7] hello time=9ms ex=java.lang.IllegalStateException
로그 추적기 v2 적용
- 차이점을 확인하기 위해 기존의 v1 패키지를 복사해서 v2으로 추가하자.
- v2 패키지 내부의 클래스명에서 v1을 v2로 변경한다.
- 각 클래스의 내부 로직에서 참고하는 타 클래스도 v2인지 확인한다.
- 컨트롤러에서 매핑 정보를
/v1/request
에서/v2/request
로 변경한다.
- TraceV2를 적용해보자.
로그추적기 v2 적용 결과
성공하는 케이스
- 실행 후 http://localhost:8081/v2/request?itemId=test로 이동해서 확인해보자.
[b7f4ae5d] OrderController.request()
[b7f4ae5d] |–>OrderService.orderItem()
[b7f4ae5d] | |–>OrderRepository.save()
[b7f4ae5d] | |<–OrderRepository.save() time=1008ms
[b7f4ae5d] |<–OrderService.orderItem() time=1008ms
[b7f4ae5d] OrderController.request() time=1009ms
실패하는 케이스
- 실행 후 http://localhost:8081/v2/request?itemId=ex로 이동해서 확인해보자.
[0a546b1c] OrderController.request()
[0a546b1c] |–>OrderService.orderItem()
[0a546b1c] | |–>OrderRepository.save()
[0a546b1c] | |<X-OrderRepository.save() time=0ms ex=java.lang.IllegalStateException: 예외 발생!
[0a546b1c] |<X-OrderService.orderItem() time=2ms ex=java.lang.IllegalStateException: 예외 발생!
[0a546b1c] OrderController.request() time=2ms ex=java.lang.IllegalStateException: 예외 발생!
로그추적기 v2 적용 결과 분석
- 트랜잭션(HTTP 요청)을 구분하고 깊이를 표현하기 위해서 TraceId 동기화가 필요하다.
- TraceId 의 동기화를 위해서는 관련 메서드의 모든 파라미터를 수정해야 한다.
- 만약 인터페이스가 있다면 인터페이스까지 모두 고쳐야 하는 상황이 발생할 수 있다.
- 로그를 처음 시작할 때는 begin() 을 호출하고, 처음이 아닐때는 beginSync() 를 호출해야 한다.
- 서비스를 무조건 컨트롤러에서 호출한다는 보장이 없다.
- 예시 : 스케졸러
- 서비스를 무조건 컨트롤러에서 호출한다는 보장이 없다.