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

Image Image

로그 추적기는 트랜잭션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

Image

TraceStatus 는 로그를 시작할 때의 상태 정보를 가지고 있다. 이 상태 정보는 로그를 종료할 때 사용된다.

  • traceId: 내부에 트랜잭션ID와 level을 가지고 있다.
  • startImeMs: 로그 시작시간이다. 로그 종료시 이 시작 시간을 기준으로 시작~종료까지 전체 수행 시간을 구 할 수 있다.
  • message 시작시 사용한 메시지이다. 이후 로그 종료시에도 이 메시지를 사용해서 출력한다.

HelloTraceV1.java

Image Image Image

주요한 메서드만 작성했고, 코드의 자세한 정보는 여기에서 확인할 수 있다.

  • TraceStauts begin(String message)
    • 로그를 시작한다.
    • 로그 메시지를 파라미터로 받아서 시작 로그를 출력한다.
    • 응답 결과로 현재 로그의 상태인 TraceStatus 를 반환한다.
  • void end(TraceStatus status)
    • 로그를 정상 종료한다. 파라미터로 시작 로그의 상태(TraceStatus )를 전달 받는다. 이 값을 활용해서 실행 시간을 계산하고, 종료시에도 시작할 때와 동일한 로그 메시지를 출력할 수 있다.
    • 정상 흐름에서 호출한다.
  • void exception(TraceStatus status, Exception e)
    • 로그를 예외 상황으로 종료한다.TraceStatus , Exception 정보를 함께 전달 받아서 실행시간, 예외 정보를 포함한 결과 로그를 출력한다.
    • 예외가 발생했을 때 호출한다.

테스트 코드 작성

Image

로그 출력 확인

Image

로그 출력 확인

Image

Reference

김영한님의 스프링 핵심 원리

나의 뇌



© 2022. by taewoo

Powered by taewoo