Skip to content

Commit 2b6c2ff

Browse files
committed
Write SpringBoot Post " Spring Boot 멀티 모듈에서 logback 환경별 설정하기 "
1 parent c69b64a commit 2b6c2ff

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
* 이번 글은 실제 운영 환경에서 적용하는 것 보다는 멀티 모듈 구조에서 환경별로 `logback.xml`을 구성한 경험을 공유하기 위해 작성했다.
17+
18+
19+
---
20+
21+
22+
## 환경 구성
23+
24+
> 이 글에서 다루는 모든 코드는 [Github](https://github.com/devFancy/kotlin-java-playground/tree/main/springboot-java-practice) 에서 확인하실 수 있습니다.
25+
>
26+
> 멀티 모듈 구성에 대한 자세한 설명은 [README.md](https://github.com/devFancy/kotlin-java-playground/blob/main/springboot-java-practice/README.md) 를 참고해 주시면 감사하겠습니다.
27+
28+
### 기술 스택
29+
30+
* Spring Boot: 3.2.5
31+
* Java: 21
32+
* Logback: Spring Boot 내장 로깅 프레임워크 사용
33+
* Gradle 8.1
34+
35+
### 멀티 모듈 구조
36+
37+
* `core:core-api`: 애플리케이션 실행 및 API 계층을 담당하는 메인 모듈이다. 다른 내부 모듈들과 연결되어 실제 서비스를 구동한다.
38+
39+
* `core:core-enum`: core-api 전반에서 공통으로 사용하는 Enum(열거형) 을 정의한 모듈이다. 도메인 간 중복을 방지하고, 일관된 값을 유지하기 위해 별도 분리하여 관리한다.
40+
41+
* `support:logging`: 공통적인 로깅 설정을 담당하는 모듈이다. 여러 서비스에서 일관된 로그 포맷을 적용할 수 있으며, 필요 시 Sentry 연동도 고려할 수 있다.
42+
43+
## logback.xml 구성
44+
45+
환경별 로깅 설정은 다음과 같이 별도의 XML 파일로 분리되어 있다.
46+
47+
> 배포 단계 흐름: `local` (개인 개발) -> `dev` (통합 개발) -> `staging` (운영 전 최종 점검) -> `live` (=prod, 실제 서비스 운영)
48+
49+
```markdown
50+
support/logging/src/main/resources/logback/
51+
├── logback-dev.xml
52+
├── logback-live.xml
53+
├── logback-local.xml
54+
└── logback-staging.xml
55+
```
56+
57+
그리고 `logging.yml` 파일에서 다음처럼 설정되어 있어, `spring.profiles.active`에 따라 자동으로 해당 설정 파일을 불러오게 된다.
58+
59+
```yaml
60+
logging.config: classpath:logback/logback-${spring.profiles.active}.xml
61+
```
62+
63+
이 구조를 통해 각 환경의 로그 패턴, 출력 대상(Appender), 로깅 레벨 등을 유연하게 관리할 수 있다.
64+
65+
66+
## logback.xml 구체적으로 살펴보기
67+
68+
### 공통 구조
69+
70+
모든 환경은 아래 공통 구성을 따른다.
71+
72+
```xml
73+
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
74+
```
75+
76+
* Spring Boot가 제공하는 기본 색상 설정과 변수(%clr, ${level:-%5p} 등)를 포함한다.
77+
78+
```xml
79+
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
80+
<encoder>
81+
<pattern>...</pattern>
82+
<charset>utf8</charset>
83+
</encoder>
84+
</appender>
85+
```
86+
87+
* 콘솔 출력용 Appender
88+
* UTF-8 인코딩 사용
89+
* 각 환경에서 동일한 패턴을 사용하며 Appender만 다르게 구성할 수도 있다.
90+
91+
### 로그 출력 패턴 예시
92+
93+
아래는 `logback-local.xml`에서 사용한 로그 출력 패턴이다.
94+
95+
```xml
96+
<pattern>
97+
%clr(%d{HH:mm:ss.SSS}){faint}|
98+
%clr(${level:-%5p})|
99+
%32X{traceId:-},
100+
%16X{spanId:-}|
101+
%clr(%-40.40logger{39}){cyan}
102+
%clr(|){faint}
103+
%m%n
104+
${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
105+
</pattern>
106+
```
107+
108+
* `%clr(...)`: Spring Boot에서 지원하는 색상 강조 기능으로 `<include ...logback/defaults.xml>` 을 통해 정의된다.
109+
110+
* `{faint}`: 회색빛(faint) 으로 출력되며, 로그 가독성을 높이기 위한 장식적 용도이다. 중요도가 낮은 항목 (예: 시간, 구분자 등)에 자주 사용된다.
111+
112+
* `%d{HH:mm:ss.SSS}`: 로그 발생 시간 (시:분:초.밀리초). 운영 환경에서는 날짜를 생략했다.
113+
114+
* `${level:-%5p}`: 로그 레벨(DEBUG, INFO, WARN, ERROR 등) 을 왼쪽 정렬 기준으로 **최소 너비 5칸**으로 출력한다. 가장 긴 로그 레벨인 ERROR(5자)에 맞춰 가독성을 높이기 위해 보통 5자 폭으로 설정한다.
115+
116+
* `%X{traceId}, %X{spanId}`: MDC에 저장된 `traceId``spanId`를 각각 32칸, 16칸 너비로 출력한다. 값이 없을 경우 빈 값으로 대체된다.
117+
주로 Spring Cloud Sleuth, Zipkin 등과 연동할 때 사용되며, 분산 트레이싱을 위한 정보로 활용된다.
118+
119+
* `%logger{39}`: 로그를 발생시킨 클래스명을 최대 39자까지 출력한다. 너무 긴 클래스명은 생략되고, 필요한 경우 패키지명 없이 `logger{0}`과 같이도 설정할 수 있다.
120+
121+
* `%m%n`: 로그 메시지를 출력하고 줄 바꿈을 수행한다.
122+
123+
* `%wEx`: 예외가 있을 경우, 간략한 요약 정보만 1~2줄로 출력한다. 전체 stack trace는 출력하지 않아 운영 환경에서 로그를 깔끔하게 유지하는 데 유리하다.
124+
125+
## 실행 및 로그 확인
126+
127+
`local` 환경에서 애플리케이션을 실행하면, 아래와 같은 로그를 확인할 수 있다.
128+
129+
> 실행 결과 예시
130+
131+
![](/assets/img/springboot/springboot-multi-module-logback-xml.png)
132+
133+
위 로그에서 traceId, spanId 값이 비어 있는 이유는 **Spring Cloud Sleuth 등 분산 추적 라이브러리를 적용하지 않았기 때문**이다.
134+
135+
이 값을 출력하고 싶다면 Sleuth 또는 Micrometer Tracing 등의 설정이 필요하다.
136+
137+
또한 `/api/log` API 요청을 통해 다양한 로그 레벨의 로그를 출력해볼 수 있다.
138+
139+
> ExamplePostController
140+
141+
```java
142+
@RequestMapping("/api")
143+
@RestController
144+
public class ExamplePostController implements ExamplePostControllerDocs {
145+
private final Logger log = LoggerFactory.getLogger(getClass());
146+
147+
@GetMapping("/log")
148+
@Override
149+
public ResponseEntity<CommonResponse<?>> logTest() {
150+
log.debug("DEBUG 레벨 로그입니다.");
151+
log.info("INFO 레벨 로그입니다.");
152+
log.warn("WARN 레벨 로그입니다.");
153+
log.error("ERROR 레벨 로그입니다.");
154+
return ResponseEntity.ok(CommonResponse.success());
155+
}
156+
}
157+
```
158+
159+
> API 실행 결과
160+
161+
![](/assets/img/springboot/springboot-multi-module-logback-xml-loglevel.png)
162+
163+
## Summary
164+
165+
* 이번 글에서는 멀티 모듈 기반의 Spring Boot 프로젝트에서 환경별 `logback.xml` 을 어떻게 구성하고 적용할 수 있는지 정리했다.
166+
167+
* 특히 `%clr`, `${level:-%5p}`, `%X{traceId}` 등 로그 패턴 설정에 사용되는 문법을 하나씩 설명하고, 실제 로그 출력 결과를 통해 그 효과를 확인했다.
168+
169+
* 다음 글에서는 Spring Filter를 활용한 HTTP 요청/응답 로그 수집과, 이를 기반으로 Sentry 혹은 Grafana 등 외부 모니터링 도구와 연동하는 방법을 이어서 소개할 예정이다.
170+
171+
## References
172+
173+
* [[Github] spring-boot-java-template](https://github.com/team-dodn/spring-boot-java-template)
174+
175+
* [Docs] https://logback.qos.ch/manual/appenders.html
86 KB
Loading
496 KB
Loading

0 commit comments

Comments
 (0)