평소에 로깅에 대해서 많이 고려하지 않고 간단하게 @slf4j 어노테이션을 통해서 간단하게 로그 확인용으로 사용하기만 해서
로깅을 어떤 상황에 사용하고 왜 사용하는지 궁금증이 생기기 시작했습니다
그리고 사이드 프로젝트로 개인 운영 서버를 몇 개 운영하는 입장에서도 로깅에 대한 필요성을 느끼고 있으며
이번에 로깅에 대해서 정리해보려고 합니다
로깅(Loggin)이란?
소프트웨어 애플리케이션이 실행되는 동안 방생하는 모든 상태,흐름,이벤트,오류 정보를 순서대로 기록으로 남기는 행위를 말한다
이 기록은 단순히 개발 중 확인용이 아닌 운영 중인 애플리케이션(서버)의 상태를 기록하고 문제를 추적하기 위한 근거 자료라고 볼수 있다
즉 이 시스템에서 어떤 일이 일어나고 있는지 확인할 수 있는 자료를 기록하는 행위이다
로깅의 필요성
1. 장애 발생
운영 서버에서 장애가 발생했을 때 먼저 언제,어떤 작업,어떤 상황에 오류가 발생했는지 파악해야 하지만 이런 정보가 남아 있지 않다면 원인 분석에 많은 시간이 소요되고 문제 해결 또한 지연될 수밖에 없다 로그를 통해 상황을 기록하여 장애 발생 시 빠르게 원인 분석을 할 수 있도록 설계할 필요가 있다
2. 성능 개선
에러가 발생하지 않더라도 특정 API,조건 등 에서 응답이 지연되거나 트래픽에 따라 병목 발생 등 성능 이슈가 발생할 수 있는데
요청 시작,처리 완료,내부 처리 흐름 등을 로그로 남겨두면 성능 병목 지점을 찾아 성능 개선에 도움이 될 수 있다
3. 모니터링
개인 서버를 운영하면서 서버에 SSH로 접속하여 로그 파악을 할 때가 많다 요청이 처리되고 있는지 오류는 발생하지 않는지 확인하는 등 여러 가지 용도로 확인을 하는데 모니터링 시스템을 도입하면 그래프 형태로 확인할 수 있지만 정확한 이슈 파악은 로그로 확인 하는 경우가 많기 때문에 모니터링 용도로도 중요하게 활용된다
로깅 레벨별 의미
로깅 레벨은 단순히 로그의 "중요도"를 구분하는 개념보다는 로그를 언제,어떤 환경에서 확인할 것인지에 대한 기준으로 볼 수 있다
TRACE: 상세한 내용을 기록할 때 사용 시스템의 내부 동작 구조를 파악하거나 실행 순서 추적에 유용하게 사용된다
DEBUG: 로직이 의도대로 동작하는지 기록할 때 사용 주로 개발 단계에서 사용된다
INFO: 시스템이 정상적으로 동작하고 있음을 기록할 때 사용 시스템의 정상 동작을 기록할 때 사용된다
(Spring 서버 실행시 처음 출력되는 로그도 INFO)

WARN:문제가 될 가능성이 있는 상황을 기록할 때 사용
ERROR: 요청이 실패했거나,시스템이 정상 동작하지 못한 상황을 기록할 때 사용
로깅 라이브러리
1. Logback
Logback은 자바 애플리케이션에서 사용하는 대표적인 로깅 구현체로 SLF4J와 함께 사용된다
Spring Boot에서 기본 로깅 구현제로 Logback이 사용되며 Web 의존성을 추가했다면 기본적으로 사용이 가능하다
2. Log4j2
Log4j2는 Apache에서 제공하는 로깅 프레임워크 비동기 로깅 기능이 강력하다는 장점이 있다
3. SLF4J(Simple Logging Facade for Java)
SLF4J(Simple Logging Facade for Java)는 자바 애플리케이션에서 사용하는 로깅 표준 인터페이스
- 로깅 라이브러리(Logback,Log4j2 등)를 직접 사용하지 않는다
- SLF4J라는 공통 인터페이스를 통해 간접적으로 사용하는 구조를 만든다
어떤 로깅 라이브러리를 쓰고 있는지 몰라도 같은 방식으로 log.info(),log.error()를 호출할 수 있도록 하는 공통 인터페이스
SLF4J로 로깅 구현하기
로깅의 사용 이유 및 라이브러리에 대해서 알아봤으니 실제로 SLF4J를 이용하여 로그를 남겨보겠습니다
Spring Boot에서는 기본적으로 SLF4J + Logback 조합이 적용되어 있기 때문에 Web 의존성만 추가했다면 바로 사용이 가능하다
1. 로그 레벨 설정
Spring Boot에서는 application.yml 에서 로그 레벨을 조절할 수 있다

- root: info → 전체 패키지는 INFO 이상만 출력
- com.example: debug → 특정 패키지만 TRACE까지 출력
하지만 특정 패키지에서 TRACE까지 출력하기 위해서 다음과 같이 적용하고 진행합니다
logging:
level:
# 특정 패키지 (example은 예시입니다)
com.example: trace
2. Controller에 로그 적용하여 출력하기
Controller 클래스를 생성하고 테스트용 API를 만들어 줍니다
@Slf4j 어노테이션을 사용하면 간단하게 로깅을 사용할 수 있습니다

서버를 실행 후 해당 요청을 보내게 되면 다음과 같이 콘솔에 로그가 출력되는 걸 볼 수 있습니다


3. 로깅 직접 커스텀해보기
지금까지는 기본 설정으로 콘솔에 로그를 간단히 출력했다
하지만 단순 콘솔 출력만으로는 실제 운영 환경에 충분하지 않다
일반적으로 로그는 단순 확인용이 아니라
파일로 저장하여 추후 문제 발생 시 원인을 분석하고 관리하는 역할을 한다
또한 로그는 날짜별로 분리하여 보관하고 일정 기간이 지나면 자동으로 삭제하는 정책을 사용하는 게 일반적이다
그리고 로그 Level에 따라 별도로 분리하여 저장하거나 운영 환경을 구분하여 설정하는 게 좋다
이처럼 운영 환경에서 사용하기 위해서는 로그를 체계적으로 관리하기 위한 별도 설정이 필요하기 때문에 커스텀하여 사용한다
그럴 때 사용하는 게 logback-spring.xml 파일이다
(1) logback-spring.xml 생성하기
다음 디렉터리에 logback-spring.xml 파일을 생성해 준다
src/main/resources/logback-spring.xml
해당 파일이 존재하면 기본 설정 대신 logback-spring.xml 파일 내용을 참조하여 사용한다
(2) 콘솔 + 파일 저장 커스텀
간단하게 로그를 파일로 저장하는 설정을 구현해 본다
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Spring Boot 색상 변환기 등록 (%clr 사용 가능) -->
<conversionRule
conversionWord="clr"
class="org.springframework.boot.logging.logback.ColorConverter"/>
<!-- 콘솔 로그 패턴 (색상 적용) -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%-5level) %clr(${PID:-}){magenta} %clr([%thread]){faint} %clr(%logger{36}){cyan} - %msg%n"/>
<!-- 콘솔 출력 -->
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 파일 저장 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 현재 사용 중인 로그 파일 -->
<!-- logs 폴더가 없으면 자동 생성된다 -->
<file>logs/application.log</file>
<!-- 날짜 기반 파일 분리 정책 -->
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--
날짜별로 로그 파일을 분리한다.
예: application.2026-02-12.log
-->
<fileNamePattern>
logs/application.%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 30일이 지난 로그 파일은 자동 삭제 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 파일에 저장될 로그 형식 정의 -->
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<!-- root는 전체 애플리케이션에 대한 기본 로그 레벨을 정의 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
적용하고 프로젝트를 실행해보면 콘솔에서는 다음과 같이 출력된다

또한 디렉터리 구조를 보면 logs\application.log 파일이 생성된 걸 볼 수 있다

해당 파일을 열어보면 다음과 같이 저장이 된걸 볼 수 있습니다

(2) ERROR 로그만 따로 저장하기
<appender name="ERROR_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>
logs/error.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss} [%level] %logger - %msg%n
</pattern>
</encoder>
</appender>
위 코드를 작성하고 root에 다음 코드를 추가해 준다
<appender-ref ref="ERROR_FILE"/>
확인해보면 ERROR 로그만 따로 파일에 저장된 걸 확인할 수 있습니다

이번 글에서는 SLF4J와 Logback의 구조를 이해하고 logback-spring.xml을 통해 로그를 직접 커스텀을 진행해 봤다
단순히 로그를 찍는 것으로 끝나는 것이 아닌 파일 분리,날짜별 관리 등 로그 설계까지 고민해보는 경험이었습니다
추후에 운영 프로젝트에 로깅을 적용해 보면 좋을 것 같습니다
'Back-end > Spring' 카테고리의 다른 글
| [Spring] Spring Security JWT 로그인 구현 필수 개념 (Session, JWT, Access / Refresh Token) (0) | 2026.01.16 |
|---|---|
| [Spring] Spring Security 기본 구조와 인증 처리 흐름 (Filter Chain) (0) | 2026.01.09 |
| [Spring] Spring Boot + MySQL 연동 & JPA 활용 심화 (2) (0) | 2026.01.03 |
| [Spring] Spring Boot + MySQL 연동 & JPA 활용 심화 (1) (0) | 2025.12.30 |
| [Spring] Spring Data JPA 어노테이션 정리 (초기화 전략,연관관계,Repository) (0) | 2025.11.06 |