어제 오늘 내일

[Spring Boot] 제발 System.out.println 쓰지 마세요! (feat. SLF4J & Logback) 본문

IT/SpringBoot

[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은 안 되나요?

이유는 간단합니다. 성능관리 때문입니다.

  1. 블로킹(Blocking) I/O: System.out은 출력하는 동안 프로그램이 잠시 멈춥니다(Block). 요청이 폭주하는 서버에서 모든 스레드가 멈칫멈칫한다면? 전체 성능이 뚝 떨어집니다.
  2. 정보 부족: 언제(Time), 누가(Thread), 어디서(Class) 로그를 남겼는지 알 수 없습니다.
  3. 제어 불가: "에러만 보고 싶은데...", "파일로 저장하고 싶은데..." 같은 설정을 할 수 없습니다. 코드를 지우지 않는 한 무조건 출력됩니다.

반면, 로깅 라이브러리를 쓰면 비동기 처리로 성능 영향을 최소화하고, 상황에 따라 골라서(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단계로 나뉩니다.

  1. TRACE: 가장 상세한 정보. (나노 단위 추적, 거의 안 씀)
  2. DEBUG: 개발 단계에서 변수 값 확인 등 디버깅용.
  3. INFO: (기본) 운영 시스템에서 "잘 돌아가고 있다"는 정보. (로그인 성공, 결제 완료 등)
  4. WARN: 에러는 아니지만 주의가 필요한 상황. (메모리 부족 임박 등)
  5. 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)

 


 

마치며

오늘의 결론입니다.

  1. System.out.println은 이제 그만! (성능 킬러입니다.)
  2. @Slf4j 어노테이션을 애용하자.
  3. 개발할 땐 debug, 운영할 땐 info 레벨을 사용하자.

이것만 지켜도 여러분의 서버는 훨씬 빠르고 안정적으로 돌아갈 것입니다.

다음 포스팅에서는 Spring Boot에서 예외(Exception)를 우아하게 처리하는 법: @ExceptionHandler@ControllerAdvice에 대해 알아보겠습니다.

도움이 되셨다면 좋아요 부탁드립니다! 😊

반응형
Comments