291 lines
9.4 KiB
Markdown
291 lines
9.4 KiB
Markdown
# Log Level 기준
|
|
|
|
## 1. 목적
|
|
|
|
이 문서는 로그 레벨의 의미와 사용 기준을 정의한다.
|
|
|
|
이 문서의 목표는 다음과 같다.
|
|
|
|
- 같은 종류의 사건이 서비스마다 다른 레벨로 찍히는 일을 줄인다
|
|
- 운영에서 필요한 신호와 디버깅용 노이즈를 구분한다
|
|
- 로그 레벨이 알림, 검색, 장애 대응에 일관되게 쓰이게 한다
|
|
- ERROR/WARN/INFO/DEBUG/TRACE의 역할을 명확히 한다
|
|
|
|
## 2. 근거 수준
|
|
|
|
- Official: Spring Boot / Spring Framework 공식 문서에서 직접 확인되는 내용
|
|
- Official + Practice: 공식 설명 위에 일반적인 운영 관행을 결합한 내용
|
|
- Project Recommendation: 이 프로젝트 구조와 운영 방식에 맞춘 규칙
|
|
|
|
## 3. 기본 원칙
|
|
|
|
### 3.1 로그 레벨은 “중요도”와 “운영 행동 필요성”을 표현한다
|
|
|
|
Spring Boot는 기본 로그 출력에 level을 포함하고, observability를 logging, metrics, traces의 세 축으로 설명한다. 이 프로젝트에서 로그 레벨은 단순 출력 강도가 아니라 운영 의미를 표현한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 레벨은 “이 사건이 얼마나 심각한가”를 표현한다
|
|
- 레벨은 “운영자가 지금 당장 봐야 하는가”를 암시한다
|
|
- 디버깅 편의를 위해 레벨을 올려 쓰지 않는다
|
|
|
|
### 3.2 기본 운영 레벨은 INFO다
|
|
|
|
프로젝트 규칙:
|
|
|
|
- production 기본 로그 레벨은 INFO
|
|
- DEBUG/TRACE는 상시 기본값으로 열지 않는다
|
|
- 장애 분석이나 특정 모듈 추적이 필요할 때 범위를 좁혀 일시적으로 올린다
|
|
|
|
이 규칙은 Spring Framework가 TRACE와 DEBUG를 과도한 fire hose가 되지 않게 다뤄야 한다고 설명하는 방향과도 맞다.
|
|
|
|
### 3.3 FATAL은 사용하지 않는다
|
|
|
|
Spring Boot 공식 문서는 Logback에는 FATAL 레벨이 없고 ERROR로 매핑된다고 명시한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- FATAL 레벨 사용 금지
|
|
- 치명적 장애도 ERROR로 기록
|
|
- “매우 치명적”이라는 구분은 레벨이 아니라 메시지, 에러 코드, 알림 정책으로 표현한다
|
|
|
|
## 4. 레벨별 기준
|
|
|
|
### 4.1 ERROR
|
|
|
|
의미
|
|
|
|
요청, 작업, 배치, 연동, 내부 처리 중 실패가 발생했고 정상 경로로 복구되지 않았음을 뜻한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 요청이 최종 실패한 경우
|
|
- 외부 연동 실패가 호출 결과 실패로 이어진 경우
|
|
- 비동기 작업/스케줄 작업이 실패로 종료된 경우
|
|
- 복구되지 않은 예외가 발생한 경우
|
|
- 데이터 정합성 문제, 시스템 오작동, 예상하지 못한 분기
|
|
|
|
이런 경우 ERROR
|
|
|
|
쓰지 말아야 할 경우
|
|
|
|
- 예외가 발생했지만 의도된 비즈니스 흐름인 경우
|
|
- 재시도로 정상 복구된 중간 실패
|
|
- validation 실패 같은 예상 가능한 클라이언트 오류를 서버 이상처럼 과장하는 경우
|
|
|
|
### 4.2 WARN
|
|
|
|
의미
|
|
|
|
즉시 실패는 아니지만 문제 가능성이 높거나, 운영자가 추후 확인할 가치가 있는 비정상 상황을 뜻한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 자동 복구되었지만 이상 징후가 있는 경우
|
|
- fallback이 실행된 경우
|
|
- 재시도 후 성공했지만 원인 추적이 필요한 경우
|
|
- 느린 외부 의존성, 느린 health indicator, 비정상 입력 패턴
|
|
- deprecation 사용, 설정 누락 대체값 적용, 비권장 경로 사용
|
|
|
|
이런 경우 WARN
|
|
|
|
Spring Boot는 느린 health indicator에 대해 기본적으로 warning 로그를 남기며, 그 임계값을 설정할 수 있다고 설명한다.
|
|
|
|
쓰지 말아야 할 경우
|
|
|
|
- 정상적인 분기
|
|
- 자주 발생하는 business rejection
|
|
- 운영상 행동이 전혀 필요 없는 정보성 사건
|
|
|
|
### 4.3 INFO
|
|
|
|
의미
|
|
|
|
서비스의 주요 정상 상태 변화와 운영상 의미 있는 사건을 뜻한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 애플리케이션 시작/종료
|
|
- 중요한 배치 시작/완료
|
|
- 의미 있는 상태 전이
|
|
- 주요 외부 연동 시작/완료
|
|
- 보안상 중요한 성공 이벤트
|
|
- 운영자가 흐름을 이해하는 데 필요한 핵심 사건
|
|
|
|
이런 경우 INFO
|
|
|
|
쓰지 말아야 할 경우
|
|
|
|
- 모든 요청 진입/종료를 무조건 INFO로 남기는 것
|
|
- 고빈도 내부 반복 처리
|
|
- 디버깅용 변수 dump
|
|
|
|
### 4.4 DEBUG
|
|
|
|
의미
|
|
|
|
장애 분석이나 개발 중 원인 파악에 도움이 되는 상세 내부 흐름 정보다.
|
|
|
|
Spring Framework는 TRACE가 DEBUG와 유사한 원칙을 따르며 과도한 로그가 되어선 안 된다고 설명한다. 이 원칙은 DEBUG에도 그대로 적용된다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 주요 분기 결정 근거
|
|
- 내부 상태 변화 상세
|
|
- 외부 API 요청/응답 요약
|
|
- 매핑 결과 요약
|
|
- 재시도/백오프/fallback 판단 근거
|
|
|
|
이런 경우 DEBUG
|
|
|
|
쓰지 말아야 할 경우
|
|
|
|
- 민감정보 원문 출력
|
|
- 너무 큰 payload 전체 dump
|
|
- 운영 기본 레벨에서 계속 쌓이면 안 되는 고빈도 로그
|
|
|
|
### 4.5 TRACE
|
|
|
|
의미
|
|
|
|
매우 세밀한 흐름 추적용 로그다.
|
|
|
|
Spring Framework는 TRACE도 DEBUG처럼 다뤄야 하며 fire hose가 되어서는 안 된다고 설명한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 프레임워크/바인딩/직렬화/세밀한 분기 추적
|
|
- 특정 문제 재현 시에만 필요한 상세 이벤트
|
|
- 고빈도 루프/반복 처리의 초미세 추적
|
|
|
|
쓰지 말아야 할 경우
|
|
|
|
- production 상시 활성화
|
|
- 요청 본문, 응답 본문, 대용량 객체 전체 출력
|
|
- 민감정보 포함 가능성이 있는 상세 dump
|
|
|
|
## 5. 상황별 권장 기준
|
|
|
|
### 5.1 요청 처리
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 정상 요청 전체를 기본적으로 INFO로 남기지 않는다
|
|
- 요청 실패는 최종 실패 시 ERROR
|
|
- 비정상 입력 패턴을 별도 관찰할 필요가 있으면 WARN
|
|
- 상세 요청 흐름은 DEBUG 이하
|
|
|
|
### 5.2 외부 API 연동
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 최종 실패: ERROR
|
|
- 재시도 후 성공: 기본 WARN
|
|
- fallback 성공: 기본 WARN
|
|
- 단일 시도 상세 요청/응답 요약: DEBUG
|
|
- payload 전문 출력: 기본 금지, 정말 필요하면 TRACE에서도 마스킹 필수
|
|
|
|
### 5.3 비즈니스 거절
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 예상 가능한 비즈니스 거절은 기본적으로 INFO 또는 무로그
|
|
- 같은 거절이 이상 징후를 뜻하면 WARN
|
|
- 정상 정책 집행을 ERROR로 기록하지 않는다
|
|
|
|
예:
|
|
|
|
- 중복 가입 시도
|
|
- 권한 없음
|
|
- 유효성 검사 실패
|
|
|
|
이런 것은 기본적으로 서버 장애가 아니다
|
|
|
|
### 5.4 예외
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 요청/작업을 실패시키는 예외: ERROR
|
|
- 재시도/대체 경로로 복구된 예외: WARN 또는 DEBUG
|
|
- controller advice에서 이미 최종 실패를 기록했다면 하위 계층 중복 ERROR 로그를 피한다
|
|
|
|
## 6. 중복 로그 방지 규칙
|
|
|
|
### 6.1 같은 실패를 여러 레이어에서 모두 ERROR로 찍지 않는다
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 한 실패에 대해 대표 ERROR 로그 한 번을 원칙으로 한다
|
|
- 하위 계층은 필요하면 DEBUG/WARN으로 맥락만 남긴다
|
|
- controller, service, client, advice가 같은 예외를 모두 stack trace와 함께 ERROR로 찍지 않는다
|
|
|
|
### 6.2 로깅 위치는 책임과 함께 정한다
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 최종 실패 책임을 가진 경계에서 대표 로그를 남긴다
|
|
- 외부 연동 세부 맥락은 client/adapter에서 DEBUG/WARN
|
|
- 공통 예외 응답 생성은 advice가 하더라도, 실제 대표 에러 로그 위치는 프로젝트 단위로 일관되게 정한다
|
|
|
|
## 7. 민감정보와 레벨의 관계
|
|
|
|
### 7.1 레벨이 낮다고 민감정보를 찍어도 되는 것은 아니다
|
|
|
|
프로젝트 규칙:
|
|
|
|
- DEBUG/TRACE라도 비밀번호, 토큰, 주민번호, 카드번호, 이메일 전체값 등 민감정보 원문 출력 금지
|
|
- 낮은 레벨은 더 상세할 수 있을 뿐, 보안 예외 구간이 아니다
|
|
- 상세 추적이 필요하면 마스킹/요약/해시 처리한다
|
|
|
|
## 8. Correlation / Trace와의 관계
|
|
|
|
Spring Boot는 tracing이 활성화되면 로그에 correlation ID를 포함할 수 있다고 설명한다.
|
|
|
|
프로젝트 규칙:
|
|
|
|
- 레벨과 무관하게 운영 로그는 trace/correlation 연결이 가능해야 한다
|
|
- 같은 오류가 여러 로그로 흩어져도 추적 가능한 키가 있어야 한다
|
|
- traceId, principal, request path 기록 규칙은 별도 문서에서 구체화한다
|
|
|
|
## 9. 운영 설정 규칙
|
|
|
|
### 9.1 production 기본값
|
|
|
|
프로젝트 권장 기본값:
|
|
|
|
- root: INFO
|
|
- 애플리케이션 주요 패키지: INFO
|
|
- noisy framework package: 필요 시 WARN
|
|
- 특정 문제 조사 시 모듈 단위로만 DEBUG/TRACE 상향
|
|
|
|
### 9.2 일시적 상향은 범위를 좁힌다
|
|
|
|
프로젝트 규칙:
|
|
|
|
- root를 DEBUG/TRACE로 올리는 것을 기본 금지
|
|
- 특정 패키지, 특정 client, 특정 기능 단위로만 조정
|
|
- 문제 해결 후 원래 레벨로 되돌린다
|
|
|
|
## 10. 금지 규칙
|
|
|
|
다음은 기본 금지다.
|
|
|
|
- FATAL 사용
|
|
- 정상 흐름을 ERROR/WARN으로 과장
|
|
- 실패 하나를 여러 레이어에서 중복 ERROR 출력
|
|
- production 기본 레벨을 DEBUG/TRACE로 설정
|
|
- DEBUG/TRACE에서 민감정보 원문 출력
|
|
- 모든 요청/응답을 INFO로 남기는 것
|
|
- 디버깅 편의 때문에 레벨 의미를 무너뜨리는 것
|
|
|
|
## 11. 체크리스트
|
|
|
|
다음 질문에 “예”로 답할 수 있어야 한다.
|
|
|
|
- 이 로그는 해당 레벨의 운영 의미와 맞는가?
|
|
- 정상 흐름을 불필요하게 경고/오류로 올리지 않았는가?
|
|
- 같은 실패를 대표 로그 한 번으로 정리하고 있는가?
|
|
- DEBUG/TRACE가 상시 fire hose가 되지 않는가?
|
|
- 민감정보가 레벨과 무관하게 보호되는가?
|
|
- tracing/correlation과 연결 가능한가?
|