Spring adv 01 - log ProtoType
ProtoType
애플리케이션의 모든 로직에 직접 로그를 남겨도 되지만, 그것보다는 더 효율적인 개발 방법이 필요하다. 특히 트랜잭션 ID와 깊이를 표현하는 방법은 기존 정보를 이어 받아야 하기 때문에 단순히 로그만 남긴다고 해결할 수 있는 것은 아니다. 요구사항에 맞추어 애플리케이션에 효과적으로 로그를 남기기 위한 로그 추적기를 개발해보자. 먼저 프로토타입 버전을 개발해보자. 아마 코드를 모두 작성하고 테스트 코드까지 작성해보자 먼저 로그 추적기를 위한 기반 데이터를 가지고 있는 TraceId , TraceStatus, HelloTraceV1 클래스를 만들어보자.
진행 요구사항
- 모든 PUBLIC 메서드의 호출과 응답 정보를 로그로 출력
- 애플리케이션의 흐름을 변경하면 안됨 로그를 남긴다고 해서 비즈니스 로직의 동작에 영향을 주면 안됨
- 메서드 호출에 걸린 시간 정상 흐름과 예외 흐름 구분 예외 발생시 예외 정보가 남아야 함 메서드 호출의 깊이 표현
- HTTP 요청을 구분 HTTP 요청 단위로 특정 ID를 남겨서 어떤 HTTP 요청에서 시작된 것인지 명확하게 구분이 가능해야 함
- 트랜잭션 ID (DB 트랜잭션X), 여기서는 하나의 HTTP 요청이 시작해서 끝날 때 까지를 하나의 트랜잭션이 라 함
정상 요청
[796bccd9] OrderController.request()
[796bccd9] |-->OrderService.orderItem()
[796bccd9] | |-->OrderRepository.save()
[796bccd9] | |<--OrderRepository.save() time=1004ms
[796bccd9] |<--OrderService.orderItem() time=1014ms
[796bccd9] OrderController.request() time=1016ms
예외 발생
[b7119f27] OrderController.request()
[b7119f27] |-->OrderService.orderItem()
[b7119f27] | |-->OrderRepository.save()
[b7119f27] | |<X-OrderRepository.save() time=0ms
ex=java.lang.IllegalStateException: 예외 발생!
[b7119f27] |<X-OrderService.orderItem() time=10ms
ex=java.lang.IllegalStateException: 예외 발생!
[b7119f27] OrderController.request() time=11ms
ex=java.lang.IllegalStateException: 예외 발생!
HTTP 요청의 사이클을 하나의 트랜잭션으로 기준을 잡고 이러한 형식의 트랜잭션 스팩을 만들 것이다. 물론 모니터링을 도입하면 편하지만, 지금은 학습의 목적
TraceId.java
로그 추적기는 트랜잭션ID와 깊이를 표현하는 방법이 필요하다. TraceId 는 단순히 id (트랜잭션ID)와 level 정보를 함께 가지고 있다.
[796bccd9] OrderController.request() //트랜잭션ID:796bccd9, level:0
[796bccd9] |-->OrderService.orderItem() //트랜잭션ID:796bccd9, level:1
[796bccd9] | |-->OrderRepository.save()//트랜잭션ID:796bccd9, level:2
TraceStatus.java
TraceStatus 는 로그를 시작할 때의 상태 정보를 가지고 있다. 이 상태 정보는 로그를 종료할 때 사용된다.
- traceId: 내부에 트랜잭션ID와 level을 가지고 있다.
- startImeMs: 로그 시작시간이다. 로그 종료시 이 시작 시간을 기준으로 시작~종료까지 전체 수행 시간을 구 할 수 있다.
- message 시작시 사용한 메시지이다. 이후 로그 종료시에도 이 메시지를 사용해서 출력한다.
HelloTraceV1.java
주요한 메서드만 작성했고, 코드의 자세한 정보는 여기에서 확인할 수 있다.
- TraceStauts begin(String message)
- 로그를 시작한다.
- 로그 메시지를 파라미터로 받아서 시작 로그를 출력한다.
- 응답 결과로 현재 로그의 상태인
TraceStatus를 반환한다.
- void end(TraceStatus status)
- 로그를 정상 종료한다. 파라미터로 시작 로그의 상태(
TraceStatus)를 전달 받는다. 이 값을 활용해서 실행 시간을 계산하고, 종료시에도 시작할 때와 동일한 로그 메시지를 출력할 수 있다. - 정상 흐름에서 호출한다.
- 로그를 정상 종료한다. 파라미터로 시작 로그의 상태(
- void exception(TraceStatus status, Exception e)
- 로그를 예외 상황으로 종료한다.
TraceStatus,Exception정보를 함께 전달 받아서 실행시간, 예외 정보를 포함한 결과 로그를 출력한다. - 예외가 발생했을 때 호출한다.
- 로그를 예외 상황으로 종료한다.
테스트 코드 작성
로그 출력 확인
로그 출력 확인
Reference
김영한님의 스프링 핵심 원리
나의 뇌