3장_ 로깅: System.out.println() 대신 로깅을 써야 하는 이유

2026. 2. 2. 11:05·Book/자바 웹 프로그래밍 Next Step

 

자바를 처음 배울 때 콘솔에 값을 찍는 용도로 제일 먼저 쓰는 API가 System.out.println()이다. 동작 확인할 때도 쓰고, 에러 원인 찾는 디버깅 용도로도 엄청 많이 쓴다. 초보일수록 “일단 찍어보자”가 습관처럼 나온다.

근데 이 방식은 실제 애플리케이션에서는 문제가 된다. 성능 때문이다.

 

 

System.out.println()이 왜 성능에 안 좋은가

System.out.println()로 디버깅 메시지를 출력하면 결국 어딘가로 “출력”을 해야 한다. 환경에 따라 콘솔/파일/스트림 등으로 나가는데, 중요한 건 이 출력 작업 자체가 꽤 비싼 작업이라는 점이다. 특히 많은 요청이 오고, 그때마다 print가 찍히기 시작하면 애플리케이션이 쓸데없는 I/O 비용을 계속 치르게 된다.

실제로 현업에서는 System.out.println()이 너무 많이 들어가 있으면:

  • 성능이 떨어지고
  • 로그가 난장판이 되고
  • 배포 전에 System.out.println()을 지우거나 주석 처리해야 하는 일이 생긴다

근데 이 “삭제/주석 처리”도 비용이다. 나중에 또 디버깅해야 하면 다시 원복하고, 또 배포 전에 지우고… 이런 흐름이 반복된다.

그래서 결론은 이거다.

System.out.println()은 학습용으로는 편하지만, 서비스 코드에서는 유지보수/성능 측면에서 최악이다.

 

 

그래서 등장한 게 “로깅 라이브러리”다

이 단점을 해결하기 위해 나온 게 로깅 라이브러리이다. 앞으로는 System.out.println()은 잊고, 로깅으로 메시지를 남기는 습관을 들이는 게 맞다.

자바 진영에서 많이 쓰는 로깅 구현체 중 하나가 Logback이다.
그런데 여기서 또 문제가 하나 있다.

  • 로깅 구현체는 종류가 많다 (Log4J, Logback, 기타 등등)
  • 더 좋은 구현체가 나오면 바꾸고 싶어진다
  • 근데 코드 전체가 특정 구현체에 종속되어 있으면 교체가 너무 힘들다

이 문제를 해결하려고 보통 SLF4J를 사용한다.

 

 

SLF4J는 “인터페이스”, Logback은 “구현체”이다

SLF4J는 “로깅 API(추상화)”이다.
실제로 로그를 출력하는 역할은 Logback 같은 구현체가 담당한다.

즉 구조는 이렇게 된다.

  • 코드에서는 SLF4J로만 로그를 작성한다
  • 실제 출력은 Logback이 한다 (pom.xml에 추가된 dependency가 그 역할)

그래서 프로젝트 코드를 보면 이런 import를 쓴다.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

즉, Logback을 코드에서 직접 부르지 않는다.

대신 pom.xml에는 Logback 구현체가 들어있다.

<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>

이렇게 해두면 나중에 더 좋은 구현체가 나오면?

  • 코드 수정 없이
  • pom.xml에서 구현체만 바꾸면 된다

이게 SLF4J를 쓰는 핵심 이유이다.

 

 

로그 레벨로 “출력되는 양”을 조절한다

로깅 라이브러리는 메시지 출력 여부를 로그 레벨로 관리한다.

대표적으로 많이 쓰는 레벨은 이거다.

`trace`, `debug`, `info`, `warn`, `error`

그리고 레벨의 “높고 낮음”은 보통 이렇게 이해하면 된다.

`trace` < `debug` < `info` < `warn` < `error`

  • 레벨이 낮을수록: 더 많은 로그를 찍는다 (세세한 정보까지)
  • 레벨이 높을수록: 더 중요한 로그만 찍는다 (경고/에러 위주)

예를 들어:

  • 설정이 `warn`이면 → `warn`, `error`만 출력된다
  • 설정이 `debug`이면 → `debug`, `info`, `warn`, `error`가 출력된다

그리고 로그 레벨은 메시지를 찍는 코드에서 결정된다.

예를 들어 `RequestHandler`에서 `log.debug(...)`를 쓰면 그 메시지는 `debug` 레벨 메시지이다.

 

 

로그를 “문자열 더하기(+)”로 만들면 성능이 떨어질 수 있다

여기서 또 중요한 성능 포인트가 하나 나온다.

예를 들어 로그를 이렇게 만들면:

log.debug("New Client Connect! Connected IP : " + connection.getInetAddress() + ", Port : " + connection.getPort());

겉보기엔 문제 없어 보이지만, 설정 레벨이 info나 warn라서 debug 로그가 출력되지 않는 상황이어도 문제가 생긴다.

왜냐하면…

  • debug()가 실제로 출력하지 않더라도
  • debug()에 넘길 인자를 만들기 위해
    "문자열 + 값 + 문자열 + 값" 계산은 먼저 실행된다

즉 출력도 안 할 로그인데도, 불필요한 문자열 연산을 매번 하게 된다.
자바에서 문자열 더하기는 생각보다 비용이 크고, 요청이 많아지면 이게 누적되어 성능을 갉아먹는다.

 

 

SLF4J의 `{ }` 포맷을 쓰면 이 문제를 피할 수 있다

SLF4J는 이 문제를 해결하려고 파라미터 바인딩 방식을 제공한다.

이렇게 쓰는 방식이다.

log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), connection.getPort());

이 방식의 장점은:

  • debug 레벨이 꺼져 있으면
  • 굳이 메시지를 만들기 위한 문자열 결합을 하지 않는다
  • 필요할 때만 포맷팅이 실행된다

즉 “동적인 로그”를 찍으면서도 불필요한 연산을 줄여서 성능을 지킨다.

결론은 이거다.

 

로깅은 + 문자열 결합이 아니라 {}
패턴을 쓰는 게 기본이다.

 

 

 

 

 


출처 : 《자바 웹 프로그래밍 Next Step》, 박재성, 로드북

'Book > 자바 웹 프로그래밍 Next Step' 카테고리의 다른 글

5장_ : Servlet으로 Hello World 출력하기  (0) 2026.02.05
5장_: 임베디드 톰캣으로 웹 서버 띄우기  (0) 2026.02.05
3장_ 요구사항 4: 302 status code 적용  (0) 2026.02.01
3장_ 요구사항3: POST방식으로 회원가입  (0) 2026.02.01
3장_ 메모: 요청 메시지의 형태  (0) 2026.01.31
'Book/자바 웹 프로그래밍 Next Step' 카테고리의 다른 글
  • 5장_ : Servlet으로 Hello World 출력하기
  • 5장_: 임베디드 톰캣으로 웹 서버 띄우기
  • 3장_ 요구사항 4: 302 status code 적용
  • 3장_ 요구사항3: POST방식으로 회원가입
sqaxe1
sqaxe1
woojoo-devlog 님의 블로그 입니다.
  • sqaxe1
    Woojoo's Devlog
    sqaxe1
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Backend (9)
        • Servlet (7)
        • Spring (2)
      • Frontend (1)
      • CS (0)
      • Book (33)
        • 자바 웹 프로그래밍 Next Step (30)
        • 테스트 주도 개발: 고품질 쾌속개발을 위한 TDD.. (1)
        • 성공과 실패를 결정하는 1%의 네트워크 원리 (2)
      • Engineering (0)
        • Testing (0)
      • Infra (6)
        • AWS (6)
      • Java (4)
      • Network (1)
      • 김영한 (28)
        • 자바 입문 (8)
        • 실전 자바 - 기본편 (6)
        • 실전 자바 - 중급편 (10)
        • 실전 자바 - 고급편 (4)
      • Web (39)
        • Web Basics (39)
      • Project (24)
        • NeoSquare (0)
        • Memo Evolution (24)
      • 정보처리기사 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    aws
    java
    개발서적
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
sqaxe1
3장_ 로깅: System.out.println() 대신 로깅을 써야 하는 이유
상단으로

티스토리툴바