개발을 하면서 Print를 찍으면서 디버깅하고 제대로 된 배포도 해본 적이 없어서 로그가 중요하단걸 알지만 로그를 재대로 다루어 본 적이 없었고 필요성도 잘 느끼지 못했다.
프로젝트를 하면서 로그 기능을 사용해보기로 했고, 공부를 했는데 공부를 하면 할수록 시스템에서 로그는 굉장히 중요하고 제대로 관리해야 한다는 것을 느끼게 되었다.
로그가 중요하다고 이것저것 막 로그를 남기는 것은 별로 좋아보이지 않았다. 실제로 console에 debug 레벨의 알람을 설정해 두었는데 실행 경로를 탐색하고 코드가 어떻게 돌아가는지 확인하는 데는 좋았지만, 불필요하게 많은 debug 알람으로 정작 중요한 에러들에 관련된 알람들을 잘 볼 수 없었다.
반대로 예외 상황에 대해서 모두 ERROR레벨로 처리하게 되니깐, 치명적인 에러나 간단간단한 에러들을 한눈에 볼 수 있었다. 하지만 이것 역시 문제가 있는 방법이 였다. 보통의 서비스에서는 일정 시간동안 에러의 수가 일정 이상이면 알람이 발생하도록 구성하는데, 사용자의 오타로 인해 발생하는 예외 역시 에러로 들어가 버리기 때문에 정작 중요한 심각한 에러 로그를 놓칠 수도 있다는 것이었다.
이러한 이유로 적정 수준의 로그 레벨을 구분하여 사용하는 것인데, 이것을 분리하는 것이 매우 중요해 보였다.
로그 레벨
앞서 이야기했듯이 로그 레벨은 해당 문제가 얼마나 중요한지 알려주는 정보이다. 로그의 레벨에 따라서 바로 처리해야 하는지 나중에 처리해야하는지 구분할 수 있게 된다.
로깅 프레임 워크들마다 지원하는 로그 레벨들이 조금씩 다르지만 레벨은 다음과 같다.
TRACE (일부 프레임 워크에서만 지원)
- 목적: 매우 세부족인 정보를 기록하는 로그 레벨
- 사용 사례: 디버깅을 위해 매우 상세한 수준에서 코드의 동작을 추적하고자 할 때 사용
- 예시: 함수 호출의 단계별 흐름, 객체의 생성 및 파괴 시점 등.
DEBUG
- 목적: 개발 혹은 테스트 단계에서 해당 기능들이 올바르게 동작하는지 확인하기 위한 로그 레벨이다.
- 사용 사례: 코드의 흐름을 추적하거나, 변수 값, 함수 호출 등을 자세히 살펴보고 싶을 때 사용한다.
- 예시: 데이터베이스 쿼리, 함수 진입/탈출 로그, 상세한 변수 상태
- 다른 레벨들과 달리 운영 환경에서는 남기고 싶지 않은 로그 메시지를 위한 레벨이다.
INFO
- 목적: 시스템의 일반적인(정상적인) 동작 상태를 나타내기 위한 로그 레벨이다.
- 사용 사례: 서비스 시작 및 종료, 중요한 비즈니스 프로세스의 시작과 끝, 상태 변경 등의 이벤트를 기록한다.
- 예시: 서버 시작 시 로드된 설정, 사용자가 다시 로그인했다는 메시지, 파일 처리 완료 등의 정보
- 시스템을 파악하는데 유익한 정보여야만 한다.
WARNING
- 목적: 시스템이 예상치 못한 상황에 직면했지만, 현재로서는 정상 작동이 가능한 상태임을 나타내는 로그 레벨이다.
- 사용 사례: 향후 문제가 발생할 수 있는 잠재적인 위험 요소를 알리기 위해 사용된다.
- 예시: 디스크 공간 부족, 메모리 사용량 경고, 비정상적이지만 치명적이지 않은 이벤트
ERROR
- 목적: 시스템이 일부 기능을 수행할 수 없음을 나타내기 위한 로그 레벨이다.
- 사용 사례: 예외 처리, 실패한 작업등 중요한 문제를 나타내며, 즉각적인 조치가 필요할 수 있다.
- 예시: 파일을 열 수 없음, 데이터 베이스 연결 실패, 중요한 요청 처리 실패 등.
CRITICAL
- 목적: 시스템 전체가 정상적으로 작동하지 않거나, 즉각적인 조치가 필요한 심각한 문제를 나타내기 위한 로그 레벨이다.
- 사용 사례: 애플리케이션의 치명적인 오류, 시스템 다운, 데이터 손실 등.
- 예시: 애플리케이션 충돌, 시스템 리소스 고갈, 주요 서비스 중단 등
여기서 운영 환경에서 중요한 것은 WARN과 ERROR 레벨을 확실히 구분하는 것이다.
앞서 이야기했듯이 예외 상황이라고 모두 ERROR처리를 하는 것은 매우 안 좋은 습관이다.
예를 들어, 사용자가 로그인 시 ID/PW 등을 오 입력하여 예외가 발생하는 것도 ERROR로 처리되기 때문이다. 이런 상황은 WARN으로 처리하고 로그인이 5번 연속 실패하는 등의 특정 기준치를 넘길 경우 ERROR레벨로 남기는 것이 좋다.
한마디로 사용자에게 노출되는 메시지에 상세한 가이드를 표시해 줌으로써 해결될 수 있는지 여부이다.
추가적으로 외부 API를 사용하는 경우, 한 두 번의 실패가 큰 영향을 미치는 상황이 아니라면 외부 API에 대한 에러 레벨은 WARN으로 둔다. 물론 아래와 같은 경우에는 ERROR 레벨로 둬야 한다.
- 결제 등 비즈니스상 치명적인 API의 경우
- 단, 잔고 부족, 인증 실패 등 고객의 실수인 경우는 WARN으로 둔다.
- 그 외 외부 결제사의 문제라면 이는 ERROR로 로그를 남겨 빠르게 인지후, 해당 결제사가 정상이 될 때까지는 미노출시키는 등의 작업을 해야만 한다.
- 재시도 전략이 없는 상태에서 하루 1번, 한 달에 1번 정도로 요청 자체가 주기적으로 적은 횟수만 수행하는 경우
- Retry 호출, 메세지큐 등 재시도 전략이 있는 게 아니면서 딱 1번씩만 호출하는 경우 재시도를 해야 하기 때문에 ERROR로 로그를 남긴다.
모니터링의 기준
- INFO: 기존 대비 +-A% 이상 차이 날 경우 알람
- WARN: 분당 B개 이상일 경우 알람
- ERROR: 분당 C개 이상일 경우 알람
참고
'Theory' 카테고리의 다른 글
[아키텍처] 모노리식 이커머스 (1) | 2024.09.18 |
---|---|
정규 표현식 (0) | 2024.06.10 |
프로그램 명명 규칙 - Naming (0) | 2024.03.15 |
호스팅이란? (0) | 2023.11.26 |
HTTP란 무엇인가? (0) | 2023.11.24 |