| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- 자바문법
- js
- 정규식
- html
- 스프링부트
- javascript
- 인텔리제이
- input
- Array
- 단위테스트
- string
- Java
- list
- Visual Studio Code
- junit5
- ArrayList
- HashMap
- 자바
- Eclipse
- 자바스크립트
- 문자열
- 배열
- 테스트자동화
- junit
- CSS
- math
- SpringBoot
- vscode
- java테스트
- IntelliJ
- Today
- Total
어제 오늘 내일
[Spring Boot] 제발 System.out.println 쓰지 마세요! (feat. SLF4J & Logback) 본문
[Spring Boot] 제발 System.out.println 쓰지 마세요! (feat. SLF4J & Logback)
hi.anna 2026. 3. 10. 11:38
개발하다가 에러가 나면 습관적으로 sysout을 치시나요?
System.out.println("여기까지 실행됨: " + data);
이 한 줄의 코드가 운영 서버에서는 치명적인 성능 저하를 일으킬 수 있다는 사실, 알고 계셨나요? 오늘은 진짜 개발자가 되기 위한 첫걸음, 로깅(Logging)에 대해 알아보겠습니다.
1. 왜 System.out.println은 안 되나요?
이유는 간단합니다. 성능과 관리 때문입니다.
- 블로킹(Blocking) I/O:
System.out은 출력하는 동안 프로그램이 잠시 멈춥니다(Block). 요청이 폭주하는 서버에서 모든 스레드가 멈칫멈칫한다면? 전체 성능이 뚝 떨어집니다. - 정보 부족: 언제(Time), 누가(Thread), 어디서(Class) 로그를 남겼는지 알 수 없습니다.
- 제어 불가: "에러만 보고 싶은데...", "파일로 저장하고 싶은데..." 같은 설정을 할 수 없습니다. 코드를 지우지 않는 한 무조건 출력됩니다.
반면, 로깅 라이브러리를 쓰면 비동기 처리로 성능 영향을 최소화하고, 상황에 따라 골라서(Level) 출력할 수 있습니다.
2. Spring Boot의 로깅 표준: SLF4J & Logback
Spring Boot는 기본적으로 'SLF4J'라는 인터페이스와 'Logback'이라는 구현체를 사용합니다.
- SLF4J (Simple Logging Facade for Java): "나를 통해 로그를 찍어!" (인터페이스/껍데기)
- Logback: "내가 실제로 찍을게!" (구현체/알맹이)
개발자는 SLF4J 인터페이스만 보고 코드를 짜면 됩니다. 나중에 구현체를 Log4j2 등으로 바꿔도 코드를 수정할 필요가 없죠.
3. 가장 쉬운 사용법: 롬복(Lombok)의 @Slf4j
옛날에는 이렇게 길게 썼습니다.
private static final Logger log = LoggerFactory.getLogger(MyService.class);
하지만 이제는 Lombok 덕분에 어노테이션 하나면 끝납니다.
@Service
@Slf4j // 이거 하나면 log 객체 자동 생성!
public class MyService {
public void logic() {
log.info("비즈니스 로직 실행 중...");
try {
// ...
} catch (Exception e) {
log.error("에러 발생!", e); // 에러 스택트레이스도 같이 출력
}
}
}
4. 로그 레벨(Level): "이건 얼마나 중요한가요?"
모든 로그를 다 남길 순 없습니다. 중요도에 따라 5단계로 나뉩니다.
- TRACE: 가장 상세한 정보. (나노 단위 추적, 거의 안 씀)
- DEBUG: 개발 단계에서 변수 값 확인 등 디버깅용.
- INFO: (기본) 운영 시스템에서 "잘 돌아가고 있다"는 정보. (로그인 성공, 결제 완료 등)
- WARN: 에러는 아니지만 주의가 필요한 상황. (메모리 부족 임박 등)
- ERROR: 심각한 문제! 즉시 조치가 필요한 에러.
설정 파일(application.yml)에서 출력 레벨을 조절할 수 있습니다.
logging:
level:
root: info # 기본적으로 INFO 이상만 찍어라 (INFO, WARN, ERROR)
com.example.mypackage: debug # 내 패키지는 DEBUG부터 찍어라 (상세하게)
이렇게 하면 운영 서버(prod)에서는 info로 설정해서 불필요한 로그를 줄이고, 개발 서버(dev)에서는 debug로 설정해서 자세히 볼 수 있습니다.
5. 로그를 파일로 저장하기
콘솔에만 찍히면 서버가 꺼졌을 때 기록이 다 날아갑니다. 파일로 남겨야겠죠?
logging:
file:
name: logs/my-server.log # 여기에 저장해라
logback:
rollingpolicy:
max-file-size: 10MB # 10MB 넘으면 새 파일 만듦
max-history: 30 # 30일 지나면 삭제 (자동 관리)
Logback은 알아서 파일을 날짜별로 나누고, 용량이 차면 압축하고, 오래된 건 지워줍니다. (Log Rolling)
마치며
오늘의 결론입니다.
System.out.println은 이제 그만! (성능 킬러입니다.)@Slf4j어노테이션을 애용하자.- 개발할 땐
debug, 운영할 땐info레벨을 사용하자.
이것만 지켜도 여러분의 서버는 훨씬 빠르고 안정적으로 돌아갈 것입니다.
다음 포스팅에서는 Spring Boot에서 예외(Exception)를 우아하게 처리하는 법: @ExceptionHandler와 @ControllerAdvice에 대해 알아보겠습니다.
도움이 되셨다면 좋아요 부탁드립니다! 😊
