코드잽에서 3차 스프린트 요구사항에 맞게 로그 프레임워크를 사용하기로 했다.
또한 로깅 전략에 대해 고민하였는데, 그 과정에 대해 기록하고자 한다.
백엔드 로깅 전략
로깅 고려한 사항
먼저 로깅에 대해 고려한 사항은 아래와 같다.
- 로깅 프레임워크 중 어떤 것을 사용할 것인가
- 어떤 로그를 남길 것인가
- 환경별 로깅 레벨 정하기
어떻게 로그를 관리할 것인가
1. 로깅 프레임워크 중 어떤 것을 사용할 것인가
로깅 프레임워크에는 주로 사용되는 Log4j, Logback, log4j2 이 3가지에 대해 조사하였고, 결과적으로는 로그백을 채택하기로 하였다.
- Log4j
- 고려하지 않음
- 지원 중단
- 보안 취약점에 대해 이슈가 있었음
- 성능적으로도 가장 좋지 않음
- 고려하지 않음
- Logback
- spring에서 디폴트 로깅 시스템인 로깅 프레임워크
- 별도의 추가 의존성 없이도 사용할 수 있음
- 자동 리로딩 등 여러 기능을 제공
필자가 이미 사용해본 경험이 있어, 수월할 것이라 생각
- log4j2
- 멀티 쓰레기 환경에서 성능상으로 가장 유리함
- 사용 시 spring에서 기본적으로 설정되어 있는 logback 의존성을 제거하고 사용해야 함
결론
Logback을 사용한다.
lms 요구사항: 서비스의 규모를 고려하여 러닝 커브가 큰 기술을 이용하여 구성하는 것 보다 간단하게나마 확인할 수 있는 정도로만 구성하기
현재 우리 서비스는 규모가 크지 않기 때문에 Logback을 사용해도 성능상 충분할 것이라 생각
또한, 별도의 의존성을 고려하지 않아도 이미 추가된 `spring-boot-starter-web`에 포함되어 있음.
Spring Boot has a LoggingSystem abstraction that attempts to configure logging based on the content of the classpath. If Logback is available, it is the first choice.
Spring Boot에는 클래스 경로의 내용을 기반으로 로깅을 구성하려고 시도하는 LoggingSystem 추상화가 있습니다. Logback을 사용할 수 있는 경우, 이것이 첫 번째 선택입니다.
다음으로는 우리 애플리케이션에서 어떤 로그 정보를 남길 것인지에 대한 고민을 시작했다.
로그는 일단 최대한 많이 남기는 게 좋다고 생각하여 각 요청과 응답, 실행된 메서드, 에러 스택 트레이스 등에 대해 남기고자 하였다.
어떤 로그를 남길 것인가
- request 정보
- 엔드포인트
- http method
- 요청 바디
헤더 등 더 필요한 경우 추가한다.
- response 정보
- response status
- 응답 바디
- 응답 소요시간
- 에러 정보
- 400대 에러인 경우 ➡️ 에러 클래스명과 메시지를 출력한다.
- 500대 에러인 경우 ➡️ 에러 클래스명과 메시지, 스택 트레이스를 출력한다.
- 메서드 실행 정보
- 실행된 메서드를 출력할 경우, 디버깅 시 메서드 실행 흐름을 파악할 수 있어 용이하다.
- 실행 메서드 명 및 실행 시간
+) request 별 쓰레드 식별값
추가로 운영환경, 그리고 개발 환경에서 여러 요청이 오게 될 경우, 이를 구분하지 못한다면 디버깅에 많은 시간이 소요될 것이라고 판단했다.
따라서 각 요청을 구분하기 위해 MDC를 활용하여 쓰레드 식별값을 출력하기로 했다.
MDC란?
Mapped Diagnostic Context의 약자로 주로 웹 애플리케이션에서 요청별 정보를 로깅하는 데 사용
멀티 쓰레드 환경에서 여러 요청이 들어올 경우, 동시에 처리되는데 이때 요청에 대한 로깅은 연속적으로 기록되므로 각각이 분리되지 않고 섞이게 된다.
이때 MDC를 사용한다면 각 요청이 실행되는 쓰레드에 식별값을 부여하여 요청을 구분할 수 있다.
그 다음으로 고민한 것은 환경별로 로그 전략을 어떻게 가져가야 할 것인가였다.
환경별 로그 전략
운영 환경별 로깅 레벨 수준이 달라야 하는 이유
- 예를 들어, dev 환경 또는 production 환경에서 모든 수준의 로그가 콘솔에 출력된다면 어떤 일이 발생할까?
애플리케이션이 종료되지 않는 한 무분별하게 로그들이 출력될 것입니다. 무수히 많은 정보들로 인해 정작 확인해야 할 정보를 찾기 힘들 수 있다.
또 배포된 인스턴스의 어딘가에 저장될 이 로그들이 너무 많다면 관리해야 할 파일이 늘어나고 그 용량이 부담될 수 있다. - 반면에, 또 local 단계에서 로그를 막게 된다면 어떨까?
내가 작성한 쿼리메서드가 어떤 쿼리로 나가는지 확인하지 못한다면? 로컬에서 디버깅을 위해 에러 상황을 재현하려는 정보를 얻을 수 없다면? 등등...
개발 시에 애플리케이션 동작을 빠르게 모니터링하고 문제를 빠르게 파악할 수 있어야 하는데, 내가 원하는 로그를 확인할 수 없다면 불편할 것이다.
따라서 우리는 각 환경별 특성에 맞게 로그 레벨을 결정해야 한다.
로컬 환경
콘솔에 출력
- spring boot -> info
- application logic -> trace
- hibernate -> trace
개발 환경
파일로 저장하며, 30일 동안의 로그 파일을 저장한다.
- 전체 -> info
운영 환경
파일로 저장하며, 30일 동안의 로그 파일을 저장한다.
- 전체 -> error
이렇게 팀 로깅 전략에 대해 고민해보았지만, 아직까지 결정하지 못한 부분이 있다.
각 운영환경에서 어느정도까지의 레벨을 남기는 것이 적절한지, 어느정도 저장해야 하는지는 사실 아직 모르겠다.
왜냐, 많이 찾아보긴 했지만 사실 우리팀은 아직까지 현업만큼 요청이 많지는 않기 때문에 더 낮은 수준까지도 저장해도 되지 않을까? 하는 생각도 들기 때문에...
일단 팀 내에서도 더 지켜보고 논의를 더 해보자고 얘기했기 때문에 조금 더 지켜보고 수준을 조정해야할 것 같다.
'우아한테크코스 6기 > 3단계' 카테고리의 다른 글
Logback MDC로 쉽게 요청 추적하기 (0) | 2024.08.11 |
---|---|
NoResourceFoundException 에 대해 알아보자 (0) | 2024.08.11 |
Intellij Debugger, 어디까지 알고 사용하고 있나요? - 신기한 기능편 (2) | 2024.07.20 |
Intellij Debugger, 어디까지 알고 사용하고 있나요? - 기초편 (1) | 2024.07.20 |
Java Annotation Processor 와 Lombok (feat. AST) (0) | 2024.07.18 |