| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- 테스트자동화
- javascript
- list
- 단위테스트
- string
- 정규식
- SpringBoot
- junit5
- java테스트
- 인텔리제이
- 자바스크립트
- 배열
- CSS
- HashMap
- ArrayList
- vscode
- Eclipse
- 자바
- junit
- 스프링부트
- input
- html
- Java
- 문자열
- js
- math
- IntelliJ
- Array
- Visual Studio Code
- 자바문법
- Today
- Total
어제 오늘 내일
[Spring Boot] "System.out.println 쓰면 혼납니다!" Logback 설정 완벽 정리 (feat. 파일 자동 삭제) 본문
[Spring Boot] "System.out.println 쓰면 혼납니다!" Logback 설정 완벽 정리 (feat. 파일 자동 삭제)
hi.anna 2026. 3. 25. 10:00
"서버가 왜 죽었죠?"
"몰라요... 로그가 다 날아갔어요..."
이런 대화가 오간다면 그 서버는 시한폭탄입니다. System.out.println은 동기 방식(Blocking I/O)이라 서버 성능을 갉아먹고, 결정적으로 파일로 남지 않아서 서버를 끄면 로그도 사라집니다.
스프링 부트의 기본 로깅 라이브러리인 Logback을 제대로 설정해서, "에러는 파일로 남기고, 30일 지난 로그는 알아서 지우는" 스마트한 시스템을 구축해 봅시다.
1. 로그 레벨 (Log Level) 이해하기
로그백은 중요도에 따라 5단계 레벨을 가집니다.
- TRACE: 나노 단위의 추적 (가장 상세함)
- DEBUG: 개발할 때 필요한 정보 (SQL 쿼리, 파라미터 등)
- INFO: 운영 시스템에서 봐야 할 정보 (서버 시작, 종료, 비즈니스 로직 성공)
- WARN: 에러는 아니지만 주의가 필요한 상황 (DB 연결 지연 등)
- ERROR: 즉시 조치가 필요한 치명적 오류 (NPE, DB 연결 실패)
핵심: 설정 파일에서
root level="INFO"라고 하면, INFO, WARN, ERROR만 찍히고 DEBUG 이하는 무시됩니다. (운영 환경에서는 보통 INFO 이상만 남깁니다.)
2. 설정 파일 만들기 ()
src/main/resources 폴더 아래에 logback-spring.xml이라는 이름으로 파일을 만드세요. 스프링 부트가 시작될 때 이 파일을 자동으로 읽어옵니다.
3. 콘솔에는 예쁘게, 파일에는 안전하게
우리의 목표는 다음과 같습니다.
- 로컬(Local): 콘솔에 알록달록하게 출력 (DEBUG 레벨)
- 운영(Prod): 파일에 저장하고, 에러만 따로 모으기 (INFO 레벨)
① 변수 정의 (로그 저장 경로 등)
<configuration>
<property name="LOG_PATH" value="./logs"/>
<property name="LOG_FILE_NAME" value="my-server-log"/>
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-40.40logger{39}) : %msg%n"/>
</configuration>
② Appender 1: 콘솔 출력 (ConsoleAppender)
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
③ Appender 2: 파일 저장 (RollingFileAppender) ★핵심★
이게 제일 중요합니다. 로그가 무한정 쌓이면 디스크가 꽉 차서 서버가 멈춥니다.
"하루에 하나씩 파일을 만들고, 30일 지나면 지워라" 설정을 해봅시다.
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>
④ 에러 로그만 따로 모으기 (ErrorAppender)
에러가 났는데 INFO 로그 수천 줄 사이에 섞여 있으면 못 찾습니다. ERROR 레벨만 따로 저장하는 파일을 하나 더 만듭니다.
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/error-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>60</maxHistory> </rollingPolicy>
</appender>
4. 프로필별 적용 ()
이제 개발 환경과 운영 환경을 분리합니다.
<springProfile name="local,dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</springProfile>
</configuration> ```
---
### 5. 실제 코드에서 사용하기 (`@Slf4j`)
이제 `System.out.println` 대신 롬복의 `@Slf4j`를 쓰세요.
```java
@Slf4j // 로거 자동 생성 (private static final Logger log = ...)
@Service
public class OrderService {
public void order() {
log.trace("가장 상세한 로그");
log.debug("디버깅용 로그");
log.info("주문이 생성되었습니다."); // 운영에 남음
log.warn("재고가 5개 미만입니다.");
log.error("결제 실패! DB 연결 오류"); // 에러 파일에 따로 저장됨
}
}
마치며
오늘의 결론입니다.
System.out.println은 성능과 관리 측면에서 최악이다.logback-spring.xml을 설정해 환경별로 로그를 다르게 관리하자.RollingFileAppender를 쓰면 디스크가 꽉 찰 걱정 없이 로그를 자동 관리할 수 있다.
이제 서버가 죽어도 당황하지 마세요. ./logs/error.log 파일만 열어보면 범인이 거기에 숨어있을 테니까요.
다음 포스팅에서는 "서버가 갑자기 멈췄는데 에러 로그도 없어요..." 메모리 누수(Memory Leak)를 잡기 위한 OOM(Out of Memory) 분석과 힙 덤프(Heap Dump)에 대해 알아보겠습니다.
도움이 되셨다면 좋아요와 댓글 부탁드립니다! 😊
