업무를 하면서 Log 코드를 흔하게 볼 수 있고, 다들 로그를 자연스럽게 쓰는 것 같은데 나는 이에 대해 잘 모르고 있다고 느껴 자연스레 로그 관련해서 공부를 해야겠다고 생각했다. 어렴풋이 코드 상황을 기록하는? 것으로 로그를 알고 있고, 로그 레벨로 무엇이 있는 정도만 알고있는 터라 인프런 강의를 통해 공부했고, 그 기반으로 이해한 내용을 기록하려 한다.
참고로 인프런에서 들은 강의는 '개발자에게 필요한 로그 관리 강의' 이다.
1. 어떤 것을 로그로 남겨야할까?
개발시 범용적으로 로그를 남기는 상황들은 다음과 같다.
- 요청/응답 로그(특히 요청): 디버깅, 성능 분석
- 오류/예외 로그 : 장애 대응
- 사용자 활동 : 감사 및 사용 분석(법적인 상황)
- 디버깅 로그 : 문제 추적 (로컬에서만 사용 권장)
- 시스템 상태 로그 : 운영 모니터링 (x) -> APM에서 다루는 게 더 나음
- 데이터베이스 쿼리 로그 : 성능 최적화를 위해 남기는 경우가 있지만, Application에서는 보통 Log로 기록하지 않음
- 보안 로그 : 침해 대응 및 방어
- 배치 작업 로그 : 백그라운드 프로세스 모니터링
이 중에서 1, 2, 3, 4의 상황은 Application Log로 남기면 좋은 상황들이다.
그 외 로그를 남기면 좋은 상황으로는 Entity 상태가 변경될 때, 변경 전/후의 값을 Log로 기록하면 변화를 파악하기에 용이하다.
2. 예외와 로그
2-2. Checked/Unchecked Exception
예외가 발생했을 경우 예외 원인 분석과 처리를 위해 로그를 남겨야하는 경우가 있을 수 있다. 그 전에 예외에 대해 정확히 짚고 넘어가려고 한다. 예외에는 checked exception과 unchecked exception이 있는데, 흔히들 checked exception은 컴파일 시점에 발생하는 에러이고, unchecked exception은 런타임 시점에 발생하는 에러라고 알고 있는데 이는 잘못되었다고 한다.
예외처리는 모두 런타임에 발생하고, checked와 unchecked의 차이는 컴파일 시점에 예외 처리를 강제 하는지 안하는지에 대한 부분이다. 이 둘의 차이는 바로 컴파일 시점에서의 예외처리 강제 여부이다. checked exception은 컴파일 시점에 예외처리를 강제하고, unchecked exception은 컴파일 시점에 예외처리를 강제하지 않는다.
2-2. 모든 Exception이 에러는 아니다
바로 다음 단계에서 구체적인 로그레벨에 대해 설명하겠지만, 일단 예외 상황이 발생했을 때 어떤 로그 레벨을 선택하는 것이 좋은지 알아보고 가자. Exception이 발생한다고 해서 모든 예외가 에러는 아니다. 그래서 Exception의 성격을 잘 파악해 로그레벨을 설정해주는 것이 필요하다.
[Info/Warn]
잘못된 URL 파라미터 등 사용자(클라이언트)가 잘못된 데이터를 넘겼을 때 발생하는 예외는 시스템에서 발생한 에러가 아니므로 Info, 혹은 Warn 레벨이 적당하다. 이 상황에서 Error를 사용하는 것은 부적절한 느낌이다.
[Error]
잘못된 데이터가 들어올 가능성이 없는 경우에 발생한 Exception 같은 경우는 발생했을 시 개발자가 직접 개입해야하는 시스템적인 문제일 가능성이 높으므로 Error 로그레벨을 사용하는 것이 적절하다.
3. 로그 레벨
로그 레벨로는 Trace, Debug, Info, Warn, Error, Fatal이 있다.
Trace
Trace 레벨은 가장 세부적인 수준의 로그 레벨로, 특징은 다음과 같다.
1) 보통 코드의 세부적인 실행 경로, 요청 바디, 메서드 실행시간 등의 데이터를 기록하는 로그 레벨이다.
2) 이 데이터들은 발생 빈도가 잦아 데이터 양이 많기에 보통 3일 동안만 보관한다.
Debug
Debug 레벨은 디버깅 목적의 로그 레벨로, 특징은 다음과 같다.
1) 서비스 개발 과정에서 주요하게 찍는 값들을 기록하거나
2) 개발 중 코드의 상태나 흐름을 이해하는 용도로 사용한다
3) 특정 조건에서 발생하는 버그를 확인하거나
4) 지켜야봐야하는 예상 에러 부분을 기록하기 위해 주료 사용한다.
5) Debug 로그 레벨도 Trace와 마찬가지로 데이터 양이 많기에 3일치의 기록만 보통 보관한다.
- Query를 확인하는 용도로는 Trace나 Debug가 적절하다.
Query 같은 경우는 로그의 양이 많고, 비즈니스적인 변화가 있지 않기 때문에 데이터를 오래 보관할 필요가 없기 때문이다.
Info
시스템의 정상적인 운영 상태를 나타내는 정보성 로그로, 중요한 이벤트나 상태 변화를 기록하기 위해 사용하는 로그 레벨이다.
주로 코드 레벨이 아닌 비즈니스 레벨에서 기록해둬야 하는 정보가 있을 때 사용하기도 한다.
Warn
잠재적으로 문제가 될 수 있는 상황을 나타내지만, 시스템 운영에는 즉각적인 영향을 주지 않는 경우에 사용하는 로그 레벨이다.
Error
치명적이지 않지만, 중요한 문제가 발생했음을 나타내는 로그 레벨이고, 복구가 필요하거나 실패한 작업을 추적해야 할 때 사용하는 로그 레벨이다.
Fatal
시스템 운영을 계속할 수 없을 정도로 심각한 오류가 발생했을 때 사용하는 로그 레벨이다.
4. Logback
4-1. Slf4j

Logback을 설명하기 전에 Slf4j부터 먼저 설명하자면, 이 프레임워크는 개발하면서 종종 사용했던 터라 비교적 익숙하다.
Slf4j는 로깅 프레임워크(Logback, Log4j, 기타 로깅 프레임워크)의 인터페이스이다. 로깅 인터페이스를 사용함으로써 로깅 프레임워크에 의존하지 않는 코드를 작성할 수 있다. 이를 PSA(Portable Service Abstraction) 이라고 한다.
4-2. Portable Service Abstraction(PSA)
특정한 구현 기술에 의존하지 않고 코드를 작성할 수 있도록 추상화 개념을 지원하는 것을 의미한다.
4-3. Logback
앞서 설명한것처럼 Logback은 로깅 프레임워크 중에 하나이고, 자바의 ./src/main/resources 경로에 logback.xml 파일을 생성해 설정 정보를 입력하면된다. 예시 코드는 다음과 같다.
<configuration>
<property name="LOG_FILE" value="application.log"/>
<!-- 콘솔 출력 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss}%-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 파일 출력 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>application.%d{yyyy-MM-dd_HH-mm}.log.gz</fileNamePattern>
<maxHistory>2</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Logger 설정 -->
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>
Logback 파일을 구성하는 태그는 다음과 같다.
<property> : 변수로 활용될 것을 선언
<appender> : 로그가 어떻게 출력될지(콘솔, 파일, 그 외)를 제어하는 역할, Logback 설정에서 핵심
<root> : 각 로그 파일들이 어떤 로그 레벨로 지정될지 설정하는 역할. 특정 레벨의 로그에는 어떤 appender를 사용할지
<encoder> : 로그 출력 형식 지정
여기에서 가장 중요한 부분은 <appender>이다. Logback을 잘 활용한다는 건 설정 파일을 잘 작성하는 것을 의미하고, appender를 현 애플리케이션 상황에 맞게 잘 설정하면 로그를 효율적이고 유용하게 분석할 수 있게 구조를 설정할 수 있다.
4-4. Logback의 <appender>
Logback의 <appender>에도 다양한 종류가 있는데, 수업에서 소개한 거라 기록해두지만 보통 ConsoleAppender와 RollingAppender를 주로 사용한다고 한다.
종류
1. ConsoleAppender
콘솔/터미널에 로그를 출력하는 설정이다. 로그가 콘솔에만 찍히기 때문에 로그 데이터를 모으고, 분석하기에는 어려움이 있다.
2. FileAppender
단일한 파일에 로그를 기록함
3. RollingAppender
시간에 따라서(예시, 일 단위로) 새로운 파일에 로그를 기록하는 형식. 일단위로 기록하는게 로그 관리에 용이함
4. SyslogAppender
OS와 상호작용시 OS로 보내는 로그파일
5. SMTPAppender
SMTP는 이메일을 보낼 때 사용하는 프로토콜. 로그를 메일로 보낼때 사용.
등등 다양한 Logback의 Appender들이 있다.
4-5. <appender>의 <maxHistory>
설정한 기간 동안 보관하는 최대 로그파일 갯수를 지정할 수 있다.
기간을 'YYYY-MM-DD'로 설정하고, <maxHistory>30</maxHistory>로 설정하면, 일 저장 로그 파일의 갯수가 최대 30개이고, 30개 일 때 새로 로그 파일이 생성된다면 FIFO 방식으로 가장 먼저 생성된 로그 파일부터 삭제된다.
4-6. Logback.xml 설정으로 Profile에 따라 다른 logback 설정하기
profile별로 발생하는 로그를 구분해서 저장할 수 있는데, 그러기 위해선 logback.xml에 아래 설정 정보를 추가한 뒤 logback-***(profile명).xml 파일을 추가한다.
<configurationo>
<springProfile name="dev">
<include resource="logback-dev.xml"/>
</springProfile>
<springProfile name="prod">
<include resource="logback-prod.xml"/>
</springProfile>
<springProfile name="default">
<include resource="logback-dev.xml"/>
</springProfile>
</configuration>'Spring' 카테고리의 다른 글
| [Log] 로그 관리, 로그 수집 및 로그 시각화 까지 로그 관리하는 방법 - 2 - (1) | 2025.07.06 |
|---|---|
| [스프링/JDBC Template] 스프링-디비1편 6-2. JDBC Template (0) | 2024.02.02 |
| [스프링/예외] 스프링-디비1 6-1. 스프링과 문제 해결 - 예외 처리, 반복 (0) | 2024.02.02 |
| [스프링/@Transactional] 4-2. 트랜잭션 AOP 이해 (0) | 2024.02.01 |
| [스프링/트랜잭션] 4-1. 스프링의 트랜잭션 (0) | 2024.02.01 |