김영한님의 Spring 핵심원리 고급편을 듣고 적는 기록입니다.
로그 추적기 - 요구사항 분석
여러분이 새로운 회사에 입사했는데, 수 년간 운영중인 거대한 프로젝트에 투입되었다. 전체 소스 코드는 수 십만 라인이고, 클래스 수도 수 백개 이상이다. 여러분에게 처음 맡겨진 요구사항은 로그 추적기를 만드는 것이다. 애플리케이션이 커지면서 점점 모니터링과 운영이 중요해지는 단계이다. 특히 최근 자주 병목이 발생하고있다. 어떤 부분에서 병목이 발생하는지, 그리고 어떤 부분에서 예외가 발생하는지를 로그를 통해 확인하는 것이 점점 중요해지고 있다. 기존에는 개발자가 문제가 발생한 다음에 관련 부분을 어렵게 찾아서 로그를 하나하나 직접 만들어서 남겼다. 로그를 미리 남겨둔다면 이런 부분을 손쉽게 찾을 수 있을 것이다. 이 부분을 개선하고 자동화 하는 것이 여러분의 미션이다
요구사항
1.모든 PUBLIC 메서드의 호출과 응답 정보를 로그로 출력
2.애플리케이션의 흐름을 변경하면 안됨
-로그를 남긴다고 해서 비즈니스 로직의 동작에 영향을 주면 안됨
3.메서드 호출에 걸린 시간
4.정상 흐름과 예외 흐름 구분
-예외 발생시 예외 정보가 남아야 함
5.메서드 호출의 깊이 표현
6.HTTP 요청을 구분
-HTTP 요청 단위로 특정 ID를 남겨서 어떤 HTTP 요청에서 시작된 것인지 명확하게 구분이 가능해야함
-트랜잭션 ID (DB 트랜잭션X), 여기서는 하나의 HTTP 요청이 시작해서 끝날 때 까지를 하나의 트랜잭션이라 함
해당 강의에서는 v0->v1->v2->v3로 순차적으로 코드를 리팩터링 한다. 인상깊게 본 부분만 기록하기로 했다.
LogTrace를 하는 싱글톤으로 등록된 스프링 빈은 인스턴스가 단 한개만 존재한다. 하지만 위의 예시처럼 여러가지 request(스레드)가 하나만 있는 인스턴스의 필드를 접근하게 되면 문제가 발생한다.
다음과 같은 결과 나오는 이유이다.
쓰레드 로컬은 해당 쓰레드만 접근할 수 있는 특별한 저장소를 말한다. 쉽게 이야기해서 물건 보관 창구를 떠올리면 된다. 여러 사람이 같은 물건 보관 창구를 사용하더라도 창구 직원은 사용자를 인식해서 사용자별로 확실하게 물건을 구분해준다. 사용자A, 사용자B 모두 창구 직원을 통해서 물건을 보관하고, 꺼내지만 창구 지원이 사용자에 따라 보관한 물건을 구분해주는 것이다
ThreadLocal을 이용해 동시성 문제를 해결한 로그 추적기를 완성할 수 있다. 그러나 주의사항으로 HTTP요청이 모두 처리되면 ThreadLocal.remove()를 반드시 해주어야 한다.
강의를 들으며 애플리케이션의 구성 영역과 사용 영역을 명확하게 나누어 OCP,DIP를 지키는 부분이 굉장히 인상깊었다(LogTraceConfig 클래스 구현).