
이 글은 프로젝트에 적절한 로그(log)를 적용하는 것의 중요성과 이를 개선하면서 얻은 교훈을 공유하기 위해 작성되었습니다.
2024년 12월부터 약 3개월간 외주 프로젝트를 진행하며, 다양한 기술과 개념을 적용할 기회가 있어 의미 있는 경험을 할 수 있었습니다. 하지만, 프로젝트 기간이 부족했던 탓에 로그를 체계적으로 활용하지 못했다는 점이 가장 아쉬웠습니다.
프로젝트가 진행되는 동안, 문득 이런 생각이 들었습니다.
"사용자의 행동을 기록하고 분석할 수 있다면, 서비스의 품질을 한층 더 높일 수 있지 않을까?"
이 고민을 바탕으로 기존 코드를 돌아보며 로그 활용을 개선해 보았습니다. 이 과정에서 로그가 필요한 이유, 개선을 통해 얻을 수 있는 이점, 그리고 개인적인 의견을 공유해보려 합니다.
로그(log)는 시스템에서 발생하는 특정 이벤트를 기록하는 데이터입니다.
예를 들어, 웹사이트에 접속하면 방문 기록이 남아 언제 어디에서 접속했는지 확인할 수 있습니다. 또, 쿠팡 같은 쇼핑몰에서 상품을 조회하거나 구매하면 이전 활동을 기반으로 추천 상품이 뜨는 것도 로그 덕분입니다.
Java에서는 로그를 5가지 레벨로 구분하여 사용합니다.
적절한 로그 레벨을 사용하면 원하는 정보를 찾기 쉽고, 로그를 효율적으로 관리할 수 있습니다.

빅데이터가 출현하기 전까지 로그는 단순히 시스템을 관리하고 오류를 감지하는 용도로만 사용되어 왔습니다. 빅데이터 기술이 발전하면서 대량 데이터를 수집, 분석하는 기술이 발전하고 자연스럽게 다양한 정보를 얻어낼 수 있는 로그의 활용이 중요해졌습니다.
기존 프로젝트에서는 로그의 일관성이 부족하고, 로그 레벨이 제대로 구분되지 않았다는 문제가 있었습니다.
@RequestMapping("/error")
public Object handleError(HttpServletRequest request ,
Model model ,
HttpServletResponse response) {
/*
오류가 발생한 케이스라면 log.error를 써야하지 않았을까?
로그 형태로 일관적으로 정의하면 더 관리가 쉽지 않을까?
*/
log.debug("filter , interceptor 에서 오류 발생 , 오류 컨트롤러에 진입합니다");
log.debug("현재 요청 => {}" , request.getRequestURI());
throw new BusinessViewException(에러메세지);
}
[문제점 분석]
❌ 오류가 발생했는데도 log.debug를 사용하여 중요도가 낮은 로그처럼 기록됨
❌ 로그의 형태가 제각각이라 필요한 정보를 빠르게 찾기 어려움
❌ 어떤 요청에서 오류가 발생했는지 명확하게 남지 않음
이러한 문제를 해결하기 위해 로그 활용 방식을 체계적으로 정리하기로 했습니다.
저는 기존 소스의 문제점을 토대로 개선해보려는 포인트를 3가지를 생각했습니다.
[1] 예외가 발생하면 log.error로 정리하자
[2] 의미있는 상태 변화에 log.info로 정리하자
[3] 사용자 추적을 위해 각 요청에 대한 로그를 기록해 활용하자
[1] 예외가 발생하면 log.error로 정리하자
기존 소스코드는 프로그램 오류가 발생하면 한 곳에서 집중 관리할 수 있도록 ControllerAdvice를 활용했습니다. 그렇다면 ControllerAdvice 영역에 공통적인 포맷의 오류 로그를 작성한다면 통일성 있는 로그 정보를 남길 수 있습니다.
[과거 소스코드]

오류 발생인데도 debug를 사용했고 무분별하게 로그를 작성한 것을 볼 수 있습니다. 이를 아래와 같이 개선해보았습니다.
[개선해본 소스코드]

무분별한 debug를 없애고 log.error를 이용해 오류 발생시 로그를 구분하였습니다. 또한 형태를 { 예외 , 요청IP , 요청메서드 , 요청자원 } 형태로 통일하였으며 누가 요청한 것인지 확인하기 위해 요청IP 정보를 추가했습니다.
사용자의 행동 로그 , 외부 모듈을 호출할 때에 로그 정보를 남기면 활용할 수 있는 정보가 다양해집니다. 예를 들어 사용자 행동 로그를 수집해 추천 기능을 개발할 수 있고, 외부 API 모듈 호출에 걸린 시간 및 결과를 로깅해 외부 모듈과의 성능 검증에도 활용할 수 있습니다.
[과거 소스코드]
고객의 연체 납부를 위한 외부 결제 모듈 API를 호출하는 소스코드입니다. 이 때도 단순히 debug로만 작성하며 로그의 기능을 제대로 활용하지 못했습니다.

[개선해본 소스코드]

오류가 아닌 중요한 정보에 대해서는 log.info를 이용하였으며 외부 모듈이 호출되는 시작시점과 종료시점을 동일한 포맷으로 기록했습니다. 오류가 발생하면 log.error를 이용해 info 와 구분을 두었습니다.
[3] 사용자 추적을 위해 각 요청에 대한 로그를 기록해 활용하자
java에는 사용자의 요청을 진행하기 전후를 가로채서 추가 기능을 부여할 수 있는 인터셉터 개념이 존재합니다. 과거 코드에서는 "요청 전"에 정당한 사용자인지 세션을 검증하거나 위조 요청 CSRF를 검증하는 용도로만 사용했습니다.
이에 개선하여 "요청 전" 과 "요청 후"에 로그를 남겼습니다.
(1)어떤 사용자가 (2)어떤 요청을 (3)언제 요구했는지를 파악할 수 있다면
프로그램이 얼마나 사용되고, 어떤 기능이 중요한 지 파악할 수 있습니다.

프로젝트 내에서 로그를 일부 개선해본 결과, 이를 통해 창출할 수 있는 다양한 효과를 확인할 수 있었습니다.
이제는 단순히 프로그램을 완성하는 것을 넘어, 로그를 활용하여 부가 데이터를 생성하고 이를 효과적으로 활용하는 능력이 더욱 중요해지고 있다고 생각합니다. 로그를 잘 활용한다면, 프로그램이 지금보다 훨씬 더 큰 가치를 제공할 수 있을 것입니다.
앞으로는 로그를 통해 수집된 데이터를 분석하고, 이를 바탕으로 새로운 인사이트를 도출하는 과정도 다뤄보겠습니다.
모두 함께 로그를 잘 활용해 봅시다! 👍