|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: " Spring Boot에서 로그를 관리하는 방법 - Logback 구조와 설정 정리 " |
| 4 | +categories: SpringBoot |
| 5 | +author: devFancy |
| 6 | +--- |
| 7 | +* content |
| 8 | +{:toc} |
| 9 | + |
| 10 | +## Prologue |
| 11 | + |
| 12 | +* 실무에서 자주 사용하는 로깅에 대해 간단히 정리하고자 이 글을 작성하게 되었다. |
| 13 | + |
| 14 | +* 현업에서 로깅을 적용하는 이유와 그 개념에 대해 한 번 정리해보려고 한다. |
| 15 | + |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## 로깅을 하는 이유 |
| 20 | + |
| 21 | +로깅은 시스템이 동작할 때 시스템의 상태 및 동작 정보를 시간 순으로 기록하는 것을 의미한다. |
| 22 | + |
| 23 | +이를 통해 개발자는 다음과 같은 장점을 얻을 수 있다. |
| 24 | + |
| 25 | +* 개발 중 혹은 운영 중 발생할 수 있는 예상치 못한 문제를 진단할 수 있다. |
| 26 | + |
| 27 | +* 다양한 정보를 수집하고 기능 개선이나 문제 추적에 활용할 수 있다. |
| 28 | + |
| 29 | +* 사용자 로그는 유의미한 분석 데이터로도 확장될 수 있다. |
| 30 | + |
| 31 | +하지만 로그를 무분별하게 남기면 |
| 32 | + |
| 33 | +* 과도한 로그 데이터로 저장 공간이 낭비되거나 |
| 34 | + |
| 35 | +* 중요한 로그를 찾기 어려워지는 문제가 발생할 수 있다. |
| 36 | + |
| 37 | +따라서 로그를 **적절한 레벨로 필터링하고, 목적에 맞는 형식으로 기록하는 전략**이 필요하다. |
| 38 | + |
| 39 | +## Logback 이란 |
| 40 | + |
| 41 | +Slf4j의 구현체로, Spring Boot 환경이라면 별도 의존성 추가 없이 기본 내장되어 있다. |
| 42 | + |
| 43 | +Logback은 Log4j에 비해 다음과 같은 장점을 가진다. |
| 44 | + |
| 45 | +* 로그 설정 변경 시 서버 재시작 없이 자동으로 리로딩된다. |
| 46 | + |
| 47 | +* 필터링 정책과 레벨 제어가 유연하다. |
| 48 | + |
| 49 | +* 성능 또한 안정적으로 검증되었다. |
| 50 | + |
| 51 | +## 로그 레벨 |
| 52 | + |
| 53 | +Logback은 총 5가지 로그 레벨을 지원한다. |
| 54 | +* `Error` : 시스템에 심각한 장애나 예외가 발생했을 때 |
| 55 | + |
| 56 | +* `Warn` : 유효성 실패나 경고성 메시지 등 예상 가능한 이슈 |
| 57 | + |
| 58 | +* `Info` : 주로 **운영 환경**에서 사용되는 레벨로, 비즈니스 흐름 상의 주요 이벤트 (예: 주문 완료, 로그인 성공 등) |
| 59 | + |
| 60 | +* `Debug` : 개발 중 내부 상태나 SQL 등 디버깅용 |
| 61 | + |
| 62 | +* `Trace` : 가장 상세한 로깅, 메서드 단위 호출까지 추적할 때 |
| 63 | + |
| 64 | +로그 레벨의 우선순위는 다음과 같다. |
| 65 | + |
| 66 | +* ERROR > WARN > INFO > DEBUG > TRACE |
| 67 | + |
| 68 | +* 만약 로그 레벨을 `INFO`로 설정했다면, INFO, WARN, ERROR 수준의 로그만 출력되며 DEBUG, TRACE 로그는 무시된다. |
| 69 | + |
| 70 | +## Logback 구조 살펴보기 |
| 71 | + |
| 72 | +Logback은 기본적으로 세 가지 주요 구성 요소로 이루어져 있다. |
| 73 | + |
| 74 | +### Logger |
| 75 | + |
| 76 | +* 로그를 기록하는 핵심 객체 |
| 77 | + |
| 78 | +* 보통 패키지명 또는 클래스명을 기반으로 정의된다. |
| 79 | + |
| 80 | +* Logger는 계층 구조를 가지며, 최상위에는 루트 로거(`ROOT`)가 존재한다. |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | +### Appender |
| 85 | + |
| 86 | +* 로그를 어떤 대상에 출력할지를 결정한다. (예: 콘솔, 파일, DB, 네트워크 등) |
| 87 | + |
| 88 | +* 하나의 Logger는 여러 Appender를 가질 수 있다. |
| 89 | + |
| 90 | + |
| 91 | + |
| 92 | +### Layout |
| 93 | + |
| 94 | +* 로그 메시지를 어떤 형식으로 출력할지 정의한다. |
| 95 | + |
| 96 | +* 자바의 `String.format()`과 유사하게 로그 포맷을 커스터마이징할 수 있다. |
| 97 | + |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +## Logback 설정 방법 |
| 102 | + |
| 103 | +Spring Boot에서는 Logback이 기본 설정되어 있어 별도 설정 없이도 사용할 수 있다. |
| 104 | + |
| 105 | +보다 세부적인 설정이 필요한 경우에는 `application.yml` 또는 `logback-spring.xml` 파일을 통해 로그 형식, 출력 대상, 로그 레벨 등을 조정할 수 있다. |
| 106 | + |
| 107 | +* `application.yml`은 단순한 설정에는 적합하지만, 복잡한 구성에는 한계가 있다. |
| 108 | + |
| 109 | +* `logback-spring.xml`은 구조화된 설정이 가능하며, `<springProfile>`을 사용한 프로파일별 설정도 유연하게 지원한다. |
| 110 | + |
| 111 | +Spring Boot에서는 반드시 `logback-spring.xml` 또는 `logback-xxx-spring.xml` 형식의 파일명을 사용해야 |
| 112 | +`<springProfile>`이나 `${spring.profiles.active}` 같은 Spring Boot 전용 기능이 정상적으로 동작한다. |
| 113 | + |
| 114 | +해당 파일은 `resources` 디렉터리에 위치시키면 된다. |
| 115 | + |
| 116 | +> 파일 구조 예시 |
| 117 | +
|
| 118 | +```markdown |
| 119 | +src/ |
| 120 | +└── main/ |
| 121 | + └── resources/ |
| 122 | + └── logback-spring.xml |
| 123 | +``` |
| 124 | + |
| 125 | +> logback-spring.xml 예시 |
| 126 | +
|
| 127 | +```xml |
| 128 | +<?xml version="1.0" encoding="UTF-8" ?> |
| 129 | +<configuration> |
| 130 | + <!-- Spring Boot의 기본 로깅 설정 포함 (색상, 기본 변수 등 사용 가능) --> |
| 131 | + <include resource="org/springframework/boot/logging/logback/defaults.xml"/> |
| 132 | + |
| 133 | + <!-- 콘솔 로그 포맷 --> |
| 134 | + <property name="CONSOLE_LOG_PATTERN" |
| 135 | + value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %clr(%5level) %cyan(%logger) - %msg%n"/> |
| 136 | + <!-- 파일 로그 포맷 --> |
| 137 | + <property name="FILE_LOG_PATTERN" |
| 138 | + value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger - %msg%n"/> |
| 139 | + |
| 140 | + <!-- 콘솔 로그 Appender --> |
| 141 | + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
| 142 | + <encoder> |
| 143 | + <pattern>${CONSOLE_LOG_PATTERN}</pattern> |
| 144 | + <charset>utf8</charset> |
| 145 | + </encoder> |
| 146 | + </appender> |
| 147 | + |
| 148 | + <!-- 파일 로그 Appender --> |
| 149 | + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| 150 | + <encoder> |
| 151 | + <pattern>${FILE_LOG_PATTERN}</pattern> |
| 152 | + </encoder> |
| 153 | + <!-- RollingPolicy: 로그 파일의 크기 증가로 인한 가독성 저하를 방지하기 위한 분할 전략 --> |
| 154 | + <!-- SizeAndTimeBasedRollingPolicy: 로그 파일을 시간과 크기 기준으로 순차적으로 분할 및 보관하는 정책 --> |
| 155 | + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| 156 | + <!-- 로그 파일명 패턴 --> |
| 157 | + <!-- 날짜별로 기록되며 maxFileSize를 넘기면 인덱스(i)를 증가시켜 새로운 이름의 로그파일에 기록을 이어간다 --> |
| 158 | + <fileNamePattern>./log/%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| 159 | + <!-- 최대 파일 사이즈 --> |
| 160 | + <maxFileSize>100MB</maxFileSize> |
| 161 | + <!-- 최대 보관 일수 --> |
| 162 | + <maxHistory>30</maxHistory> |
| 163 | + </rollingPolicy> |
| 164 | + </appender> |
| 165 | + |
| 166 | + <!-- 로거 설정 --> |
| 167 | + <logger name="org.springframework" level="WARN"/> |
| 168 | + <logger name="com.example" level="INFO"/> |
| 169 | + |
| 170 | + <!-- 루트 로거 설정 --> |
| 171 | + <root level="INFO"> |
| 172 | + <appender-ref ref="CONSOLE"/> |
| 173 | + <appender-ref ref="FILE"/> |
| 174 | + </root> |
| 175 | + |
| 176 | +</configuration> |
| 177 | +``` |
| 178 | + |
| 179 | +이와 같은 방식으로 `logback-spring.xml` 한 개의 파일만으로도 |
| 180 | +환경(profile)에 따라 유연한 설정이 가능하고, 콘솔 및 파일 로그를 분리해 효율적으로 관리할 수 있다. |
| 181 | + |
| 182 | +특히 `RollingPolicy`를 적용하면 로그가 일정 크기 이상 쌓이는 것을 방지하면서, 가독성과 유지 관리 측면에서도 유리하다. |
| 183 | + |
| 184 | +로그는 단순 기록이 아니라 시스템 운영과 문제 해결의 핵심 도구이기 때문에, 상황에 맞는 구조와 설정을 잘 갖추는 것이 중요하다. |
| 185 | + |
| 186 | +## References |
| 187 | + |
| 188 | +* [Logback 으로 쉽고 편리하게 로그 관리를 해볼까요? ⚙️](https://tecoble.techcourse.co.kr/post/2021-08-07-logback-tutorial/) |
| 189 | + |
| 190 | +* [LogBack을 통한 효율적인 로그 관리](https://velog.io/@pgmjun/LogBack%EC%9D%84-%ED%86%B5%ED%95%9C-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC) |
0 commit comments