AOP를 공부하다보면 대표적인 Cross cutting concern의 예시로 로깅이 언급된다.
컨트롤러 어노테이션을 달고 다니는 오브젝트의 메서드들을 프록시로 감싸서 실행시간을 측정하는 것이 대표적인 로깅의 예시인데, 별로 마음에 들지 않는다. 아래 예시를 보자.
예제 수준의 로깅 코드다. 로깅 메세지를 보면 "-----(대충몇개)----> Respons : {} ~" 식으로 되어 있다.
그러면 거대한 시스템의 경우 초당 수십만개의 로그가 쌓이는데, 저렇게 로깅을 해도 될까?
유튜브 채널 EO에 우아한형제들 전 CTO, 현 CEO인 분이 나와서 얘기하시기를, 평시 리퀘스트는 초당 만개, 이벤트 시에는 200만개가 넘게 들어온다고 한다.
그러면 저런 문자열이 리퀘스트 *2 개만큼 생기고, 컨트롤러 로깅뿐만 아니라 비지니스 로직 상에서 로깅이 필요한 모든 부분에서 로그 메세지가 쏟아져 나올텐데, 임의의 개수의 하이픈과 구조화되어 있지 않은 메세지는 로그 분석을 어렵게 한다.
즉 로그 분석을 위해 데이터 클렌징과 자연어 처리까지 해야한다. 물론 엘라스틱서치를 사용한다면 어느정도 문제는 해결되겠지만, 그래도 만들 때부터 잘 만들어놓는게 좋다. 그래서 로그메세지는 정형화된, 구조적인 데이터이어야 한다.
백엔드 개발을 처음 하는 것이기 때문에 구조화된 데이터를 만드는 기준을 찾기 위해 열심히 한국어, 영어로 구글링해봤지만 모두 warn이나 info와 같은 로그 레벨에 대해서만 나오고 로그 메세지를 어떻게 구성해야 하는지는 찾을 수 없었다.
그래서 재밌게 보던 유튜브 채널, 판교 뚜벅초님에게 물어봤다.
https://www.youtube.com/channel/UCZ3dxObRPEJzoryEyQqmhWg
의외로 답은 단순했다. 바로 JSON으로 만드는 것!
Json은 대표적인 semi-structured 데이터인데, 주로 api 통신에만 사용하다보니 그 본질을 잊고 말았다.
JSON으로 나타내기 위해 로그 메세지별로 모델을 만들어 ObjectMapper로 문자열로 바꿀려고 했으나, 다른 구조의 로그 메세지마다 클래스를 만들기엔 부담스럽고, Map 형태로 나타내기엔 로그 메세지를 한곳에 모아보기 힘들 것같아 Enum으로 구현했다.
하지만 조금씩 기능을 덧붙일 수록 Enum 자체도 커져 관리하기 힘들고, 로그 메세지가 바뀌면 다시 빌드해야하는 문제점이 있다.
그래서 로그 메세지 정보는 외부에서 문자열 타입의 맵인 property 자료구조로 관리하고 (properties 파일 혹은 yml 파일로 저장한다.)
Spring Cloud Config를 이용해 로그 메세지 수정 시 다시 빌드할 필요 없이 관리하는 것이 적합하다. 차근차근 수정해나가야겠다.
덧붙이자면, Cross cutting concern을 해결하는 방법으로 aop뿐만 아니라 리버스프록시(게이트웨이)를 활용하는 방법도 있다.
커버 통나무 이미지 출처: 땔깜툰
'자바' 카테고리의 다른 글
JVM 스레드에 대한 고찰 및 스레드풀 튜닝 전략 (0) | 2022.09.02 |
---|---|
BufferedWriter를 Integer와 쓸 때 유의점 (0) | 2021.09.29 |
컴파일과 빌드의 차이 (0) | 2021.07.23 |
AssertJ - isEqaulTo와 isSameAs의 차이 (0) | 2020.12.29 |