반응형
Java 예외 로그 전략 완벽 이해하기
실무에서 장애가 발생했을 때 가장 먼저 보는 것은 무엇일까요?
정답은:
로그(Log)
입니다.
아무리 예외 처리를 잘 해도 로그가 잘못 남아 있으면:
- 원인 분석 불가
- 장애 복구 지연
- 운영 비용 증가
문제가 발생합니다.
실제로 실무에서는:
예외 처리보다
예외 로그를 어떻게 남길 것인가가
더 중요할 때가 많다.
1. 가장 흔한 실수
초보자가 가장 많이 하는 코드
try {
...
} catch(Exception e) {
e.printStackTrace();
}
2. 왜 문제일까?
운영 서버에서는 안 보임
대부분 서버는
stdout
stderr
를 직접 보지 않습니다.
로그 검색 불가
e.printStackTrace();
는 로그 시스템과 연동 안 됨.
로그 포맷 통일 안 됨
운영 환경에서는:
- Elasticsearch
- Kibana
- Datadog
- Grafana
등에서 검색해야 함.
3. 실무 표준
보통:
SLF4J
Logback
조합 사용.
4. 기본 형태
private static final Logger log =
LoggerFactory.getLogger(
UserService.class
);
5. 예외 발생 시
catch(Exception e) {
log.error("회원 조회 실패", e);
}
6. 왜 e를 따로 넘길까?
좋은 코드
log.error("회원 조회 실패", e);
나쁜 코드
log.error(
"회원 조회 실패 : " +
e.getMessage()
);
7. 차이점
좋은 코드:
메시지
+
전체 StackTrace
출력.
나쁜 코드:
메시지만 출력
됨.
8. StackTrace가 중요한 이유
예:
NullPointerException
만 봐서는 부족.
실제로 필요한 정보
어디서 발생했는가?
어떤 경로로 호출됐는가?
예
UserService.java:52
이 정보가 핵심.
9. 로그 레벨 이해
매우 중요.
TRACE
매우 상세
DEBUG
개발용
INFO
정상 흐름
WARN
문제 가능성 있음
ERROR
실패 발생
10. 예외는 무조건 ERROR?
의외로 아님.
예
if(user == null) {
throw new UserNotFoundException();
}
이건 비즈니스적으로 정상 가능 상황.
실무에서는
log.warn(...)
정도 사용하는 경우도 많음.
11. 로그 중복 문제
실무에서 매우 중요.
안 좋은 코드
try {
} catch(Exception e) {
log.error("Service 실패", e);
throw e;
}
Controller
catch(Exception e) {
log.error("Controller 실패", e);
throw e;
}
GlobalExceptionHandler
log.error("최종 실패", e);
12. 결과
같은 예외가
3번 출력
됨.
13. 이것이 로그 폭탄
실제 장애 시
로그 수백만 건
발생 가능.
14. 실무 권장
로그는 보통
최종 처리 지점
에서만 남김.
예
ControllerAdvice
15. 좋은 구조
Repository
↓
Service
↓
Controller
↓
ControllerAdvice
예외는 계속 던지고
throw e;
로그는
@ControllerAdvice
에서 한 번만.
16. 예외를 잡고 무시하면 안 됨
매우 중요.
안 좋은 코드
catch(Exception e) {
}
또는
catch(Exception e) {
log.error("에러");
}
17. 문제
예외 사라짐.
결과
시스템은 실패했는데
성공한 것처럼 보임
18. 예외를 다시 던져야 함
catch(Exception e) {
log.error("실패", e);
throw e;
}
또는
throw new BusinessException(e);
19. 개인정보 로그 주의
매우 중요.
안 좋은 예
log.info(
"password={}",
password
);
또는
log.info(
"주민번호={}",
rrn
);
20. 절대 금지 대상
대표적으로:
비밀번호
주민번호
카드번호
토큰
Access Token
Refresh Token
21. 로그 마스킹
예
010-1234-5678
↓
010-****-5678
22. 예외 로그 포맷 추천
실무 예시
log.error(
"[USER] 회원 조회 실패. id={}",
userId,
e
);
23. 왜 좋을까?
검색 가능.
예
[USER]
검색.
24. MDC란?
실무 고급 주제.
MDC
(Mapped Diagnostic Context)
목적
요청별 식별자 저장
예
MDC.put(
"traceId",
UUID.randomUUID()
);
25. 로그 결과
[traceId=ABC123]
회원 조회 실패
26. 왜 중요할까?
MSA 환경에서는
서버 A
↓
서버 B
↓
서버 C
흐름 추적 필요.
27. Trace ID
대표적으로:
OpenTelemetry
또는
Spring Cloud Sleuth
(현재는 Micrometer Tracing 기반으로 발전)
사용.
28. 예외 체이닝 로그
좋은 코드
catch(SQLException e) {
throw new UserException(e);
}
로그
log.error(
"회원 조회 실패",
e
);
결과
UserException
↓
SQLException
전부 출력.
29. 실무 로그 레벨 전략
| 상황 | 레벨 |
| 정상 요청 | INFO |
| 디버깅 | DEBUG |
| 복구 가능 문제 | WARN |
| 시스템 실패 | ERROR |
30. 자주 하는 실수
printStackTrace()
실무 금지 수준.
로그 중복
한 예외 여러 번 출력.
예외 삼키기
catch(Exception e){}
민감 정보 출력
보안 사고 가능.
모든 예외 ERROR
로그 오염 발생.
31. Spring 실무 패턴
Repository
↓
Service
↓
Controller
↓
@ControllerAdvice
↓
로그 기록
↓
응답 반환
32. 핵심 흐름 요약
예외 발생
↓
전파
↓
최상위 처리
↓
로그 1회 기록
↓
응답 반환
33. 가장 중요한 핵심 한 줄
좋은 예외 로그는
예외를 많이 남기는 것이 아니라
원인을 한 번에 찾을 수 있게 남기는 것이다.
34. 면접 단골 질문
Q. printStackTrace()를 사용하면 안 되는 이유는?
로그 시스템 연동 불가
운영 환경 검색 불가
포맷 관리 불가
Q. 로그는 어디서 남겨야 하나요?
최상위 예외 처리 지점
(ControllerAdvice)
Q. 예외를 잡고 로그만 남기면 되나요?
안 됨
재전파하거나
비즈니스 예외로 변환 필요
다음 글은 "실무 예외 처리 패턴" 으로 진행하면 됩니다.
여기서부터는 지금까지 배운:
- Exception
- RuntimeException
- Custom Exception
- Logging
- ControllerAdvice
를 전부 연결해서 실제 Spring 프로젝트 구조로 들어가게 됩니다.
반응형
'language > java' 카테고리의 다른 글
| Spring @ExceptionHandler 완벽 이해하기 (0) | 2026.05.29 |
|---|---|
| Java/Spring 실무 예외 처리 패턴 완벽 이해하기 (0) | 2026.05.29 |
| Java 커스텀 예외(Custom Exception) 설계 완벽 이해하기 (1) | 2026.05.29 |
| Java try-with-resources 원리 완벽 이해하기 (0) | 2026.05.29 |
| Java try-catch-finally 흐름 완벽 이해하기 (0) | 2026.05.29 |
댓글