🌿 Spring Boot Logging: Logback 설정 최적화 대작전! 🚀
안녕하세요, 개발자 여러분! 오늘은 Spring Boot의 로깅 시스템, 특히 Logback 설정을 최적화하는 방법에 대해 깊이 있게 파헤쳐볼 거예요. 로깅이 뭐 별거냐고요? ㅋㅋㅋ 어림도 없죠! 로깅은 애플리케이션의 눈과 귀라고 할 수 있어요. 제대로 설정하면 개발 생산성과 운영 효율성이 쑥쑥 올라간다고요! 😎
자, 이제부터 Spring Boot와 Logback의 세계로 빠져볼까요? 준비되셨나요? 그럼 고고씽~! 🏃♂️💨
🌊 Spring Boot와 Logback의 만남: 로깅의 새로운 지평
Spring Boot는 기본적으로 Logback을 로깅 프레임워크로 사용해요. 왜 하필 Logback일까요? 그건 바로 Logback이 성능과 유연성 면에서 다른 로깅 프레임워크들을 압도하기 때문이에요! 👑
Logback은 Log4j의 후속작으로, 더 빠르고 메모리 효율적이며, 자동 리로드 같은 쿨한 기능들을 제공해요. Spring Boot와 함께라면 거의 완벽한 조합이라고 할 수 있죠! 😍
🔍 Logback의 주요 특징:
- 빠른 실행 속도와 낮은 메모리 점유율
- XML, Groovy 기반의 설정 가능
- 로그 파일 자동 압축 및 롤오버
- 조건부 처리를 통한 유연한 설정
- 필터를 이용한 세밀한 로그 제어
이런 특징들 덕분에 Logback은 대규모 엔터프라이즈 애플리케이션부터 소규모 프로젝트까지 두루두루 사용되고 있어요. 심지어 재능넷 같은 재능 공유 플랫폼에서도 Logback을 활용해 시스템 모니터링과 디버깅을 효율적으로 하고 있다고 해요! 👏
자, 이제 Logback이 얼마나 대단한지 알겠죠? 그럼 이제부터 본격적으로 Logback 설정을 최적화하는 방법에 대해 알아볼게요. 준비되셨나요? Let's dive in! 🏊♂️
🛠 Logback 설정의 기본: logback-spring.xml
Logback 설정의 핵심은 바로 logback-spring.xml
파일이에요. 이 파일만 제대로 작성하면 여러분의 로깅 시스템은 그야말로 날개를 단 듯이 날아오를 거예요! ✈️
먼저, 기본적인 logback-spring.xml
파일의 구조를 살펴볼까요?
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
이게 바로 가장 기본적인 Logback 설정이에요. 하나씩 뜯어볼까요? 🔍
<configuration>
: Logback 설정의 루트 엘리먼트예요.<appender>
: 로그 메시지를 어디에 출력할지 정의해요. 여기서는 콘솔에 출력하도록 설정했어요.<encoder>
: 로그 메시지의 형식을 정의해요.<pattern>
: 실제 로그 메시지의 패턴을 정의해요. 시간, 스레드, 로그 레벨, 로거 이름, 메시지 순서로 출력되도록 했어요.<root>
: 루트 로거의 설정이에요. 모든 로거의 부모가 되는 로거죠.
이 기본 설정만으로도 로그를 출력할 수 있지만, 우리는 여기서 멈추지 않을 거예요! 더 나은, 더 효율적인 로깅 시스템을 만들어볼 거니까요! 💪
💡 Pro Tip: logback-spring.xml
파일은 src/main/resources
디렉토리에 위치시키세요. Spring Boot가 자동으로 이 파일을 찾아 설정을 적용할 거예요!
자, 이제 기본적인 설정 파일의 구조를 알았으니, 본격적으로 이 파일을 튜닝해볼까요? 여러분의 애플리케이션에 날개를 달아줄 시간이에요! 🚀
🎨 Logback 설정 최적화: 로그 레벨 조정의 마법
로그 레벨은 로깅 시스템의 심장이라고 할 수 있어요. 적절한 로그 레벨 설정은 필요한 정보만을 효과적으로 수집하고, 불필요한 로그로 인한 성능 저하를 방지할 수 있죠. 그럼 어떻게 로그 레벨을 최적화할 수 있을까요? 🤔
Logback에서 제공하는 로그 레벨은 다음과 같아요 (낮은 순서부터):
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
각 레벨의 특징을 살펴볼까요?
🎭 로그 레벨의 특징:
- TRACE: 가장 상세한 로그 레벨. 개발 중 매우 자세한 정보가 필요할 때 사용해요.
- DEBUG: 개발 시 디버깅 목적으로 사용해요. 운영 환경에서는 보통 비활성화합니다.
- INFO: 일반적인 작동 정보를 나타내요. 운영 환경의 기본 로그 레벨로 많이 사용돼요.
- WARN: 잠재적인 문제를 나타내지만, 애플리케이션은 계속 실행될 수 있는 상황이에요.
- ERROR: 심각한 문제가 발생했음을 나타내요. 즉시 조치가 필요한 상황이죠.
자, 이제 이 로그 레벨을 어떻게 설정하면 좋을까요? 여기 몇 가지 팁을 드릴게요! 👇
- 패키지별 로그 레벨 설정: 애플리케이션의 각 패키지마다 다른 로그 레벨을 설정할 수 있어요. 예를 들어, 데이터베이스 관련 패키지는 좀 더 상세한 로그가 필요할 수 있죠.
- 환경별 로그 레벨 설정: 개발 환경과 운영 환경의 로그 레벨을 다르게 가져가는 것이 좋아요. 개발 환경에서는 DEBUG 레벨로, 운영 환경에서는 INFO 레벨로 설정하는 식이죠.
- 동적 로그 레벨 변경: 운영 중에도 로그 레벨을 동적으로 변경할 수 있도록 설정하면 매우 유용해요. 문제 상황이 발생했을 때 로그 레벨을 일시적으로 낮춰서 더 자세한 정보를 얻을 수 있거든요.
이런 설정을 logback-spring.xml
에 어떻게 반영할 수 있을까요? 다음 예제를 봐주세요:
<configuration>
<!-- 콘솔 애펜더 설정 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 루트 로거 설정 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<!-- 패키지별 로그 레벨 설정 -->
<logger name="com.example.myapp.controller" level="DEBUG"/>
<logger name="com.example.myapp.service" level="INFO"/>
<logger name="com.example.myapp.repository" level="WARN"/>
<!-- 스프링 프레임워크 관련 로그 레벨 설정 -->
<logger name="org.springframework" level="INFO"/>
<logger name="org.hibernate" level="WARN"/>
</configuration>
이렇게 설정하면 각 패키지마다 다른 로그 레벨을 적용할 수 있어요. 컨트롤러는 DEBUG 레벨로 상세하게, 서비스 계층은 INFO 레벨로, 리포지토리 계층은 WARN 레벨로 설정했네요. 스프링과 하이버네이트 관련 로그도 따로 설정했고요.
이런 식으로 로그 레벨을 조정하면, 필요한 정보는 충분히 얻으면서도 불필요한 로그로 인한 성능 저하를 방지할 수 있어요. 완전 일석이조 아니겠어요? 😉
💡 Pro Tip: 재능넷 같은 플랫폼을 운영할 때는, 사용자 활동과 관련된 중요한 이벤트(예: 거래 성사, 회원 가입 등)는 INFO 레벨로, 시스템 내부 동작은 DEBUG 레벨로 설정하는 것이 좋아요. 이렇게 하면 중요한 비즈니스 로직은 놓치지 않으면서도, 필요할 때 상세한 시스템 동작도 확인할 수 있거든요!
자, 이제 로그 레벨 설정의 마법을 익혔으니, 다음 단계로 넘어갈 준비가 되었나요? 로그 출력 형식을 예쁘게 꾸미는 방법을 알아볼 차례예요! 🎨✨
💅 로그 메시지 예쁘게 꾸미기: 패턴 레이아웃의 마법
로그 메시지를 예쁘게 꾸미는 것, 단순히 미적인 이유만은 아니에요. 잘 구성된 로그 메시지는 가독성을 높이고 문제 해결 시간을 단축시켜줘요. 그럼 어떻게 로그 메시지를 꾸밀 수 있을까요? 바로 패턴 레이아웃을 사용하는 거예요! 🎭
Logback의 패턴 레이아웃은 정말 강력해요. 시간, 로그 레벨, 스레드 이름, 로거 이름, 메시지 등 다양한 정보를 원하는 형식으로 조합할 수 있죠. 몇 가지 유용한 패턴 요소를 살펴볼까요?
🎨 유용한 패턴 레이아웃 요소:
%d{패턴}
: 날짜와 시간을 표시해요. 예:%d{yyyy-MM-dd HH:mm:ss.SSS}
%thread
: 현재 스레드 이름을 표시해요.%-5level
: 로그 레벨을 5자리로 맞춰 표시해요. '-'는 왼쪽 정렬을 의미해요.%logger{길이}
: 로거 이름을 표시해요. 길이를 지정하면 긴 이름을 축약할 수 있어요.%msg
: 실제 로그 메시지를 표시해요.%n
: 줄바꿈을 의미해요.%highlight(패턴){색상 스타일}
: 지정한 패턴에 색상을 입혀요.
이런 요소들을 조합해서 멋진 로그 패턴을 만들어볼까요? 여기 예시가 있어요:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
이 패턴을 사용하면 로그가 이렇게 출력돼요:
2023-06-15 14:30:45.123 [main] INFO c.e.MyApp - 애플리케이션이 시작되었습니다.
2023-06-15 14:30:46.234 [http-nio-8080-exec-1] DEBUG c.e.c.UserController - 사용자 로그인 시도: user123
2023-06-15 14:30:46.345 [http-nio-8080-exec-1] WARN c.e.s.UserService - 잘못된 비밀번호 입력: user123
어때요? 훨씬 보기 좋고 정보도 한눈에 들어오죠? 😎
하지만 여기서 끝이 아니에요! 더 멋진 기능들이 기다리고 있답니다. 예를 들어, MDC(Mapped Diagnostic Context)를 사용하면 로그에 추가적인 컨텍스트 정보를 넣을 수 있어요. 재능넷 같은 플랫폼에서는 이런 기능이 특히 유용할 거예요. 사용자 ID나 세션 ID 같은 정보를 모든 로그에 자동으로 포함시킬 수 있거든요!
MDC를 사용하려면, 먼저 코드에서 MDC에 값을 넣어줘야 해요:
import org.slf4j.MDC;
// 컨트롤러나 인터셉터에서
MDC.put("userId", user.getId());
MDC.put("sessionId", session.getId());
// 로직 실행 후
MDC.clear(); // 꼭 클리어 해주세요!
그리고 로그 패턴에 MDC 값을 포함시키면 돼요:
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %X{userId} %X{sessionId} - %msg%n</pattern>
이렇게 하면 로그가 이런 식으로 출력돼요:
2023-06-15 14:35:12.345 [http-nio-8080-exec-2] INFO c.e.c.UserController - user123 ABC123XYZ - 사용자가 프로필을 업데이트했습니다.
어때요? 이제 각 로그가 어떤 사용자, 어떤 세션에서 발생했는지 한눈에 알 수 있죠? 이런 식으로 MDC를 활용하면 로그 분석이 훨씬 쉬워져요. 특히 재능넷 같은 다중 사용자 플랫폼에서는 정말 유용할 거예요! 👍
💡 Pro Tip: 로그 패턴을 설계할 때는 항상 가독성과 성능의 균형을 고려하세요. 너무 많은 정보를 포함시키면 로그 파일 크기가 빠르게 증가할 수 있어요. 꼭 필요한 정보만 포함시키고, 로그 로테이션과 압축 전략을 잘 설정하는 것이 중요해요!
자, 이제 로그 메시지를 예쁘고 유용하게 꾸미는 방법을 배웠어요. 다음은 로그를 어디에 어떻게 저장할지 알아볼 차례예요. 파일 애펜더와 로그 로테이션의 세계로 들어가볼까요? 🚪✨
📁 로그 파일 관리의 달인되기: 파일 애펜더와 로그 로테이션
콘솔에 로그를 출력하는 것도 좋지만, 실제 운영 환경에서는 로그를 파일로 저장하는 것이 훨씬 더 유용해요. 그런데 여기서 한 가지 문제가 생겨요. 로그 파일이 무한정 커지면 어떡하죠? 🤔 바로 이때 필요한 게 파일 애펜더와 로그 로테이션이에요!
파일 애펜더는 말 그대로 로그를 파일에 추가(append)하는 역할을 해요. 그리고 로그 로테이션은 로그 파일이 특정 조건(크기나 시간)에 도달했을 때 새로운 파일을 만들고 이전 파일을 보관하는 기능이에요. 이 두 가지를 잘 조합하면 로그 관리가 한결 수월해져요!
자, 그럼 Logback에서 어떻게 파일 애펜더와 로그 로테이션을 설정하는지 살펴볼까요? 🧐
<configuration>
<property name="LOG_PATH" value="./logs" />
<property name="LOG_FILE_NAME" value="myapp" />
<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.SSS} [%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}.%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
우와, 좀 복잡해 보이죠? ㅋㅋㅋ 하나씩 뜯어볼게요! 😉
<property>
: 로그 파일 경로와 이름을 변수로 정의해요. 나중에 재사용하기 편하죠!<appender>
: RollingFileAppender를 사용해요. 이게 바로 로그 로테이션의 핵심이에요!<file>
: 현재 작성 중인 로그 파일의 경로를 지정해요.<encoder>
: 로그 메시지의 형식을 정의해요. 아까 배운 패턴 레이아웃을 여기서 사용하면 돼요.<rollingPolicy>
: 로그 로테이션 정책을 정의해요. 여기서는 시간 기반 정책을 사용했어요.<fileNamePattern>
: 로테이션된 로그 파일의 이름 패턴을 정의해요. 여기서는 날짜와 인덱스를 포함하고, gz로 압축하도록 했어요.<timeBasedFileNamingAndTriggeringPolicy>
: 파일 크기 기반의 트리거 정책을 추가로 설정했어요. 10MB마다 새 파일을 만들어요.<maxHistory>
: 최대 30일치의 로그 파일만 보관하도록 설정했어요.
이렇게 설정하면, 로그 파일이 하루에 한 번씩, 또는 10MB가 될 때마다 새로운 파일로 롤오버되고, 30일이 지난 파일은 자동으로 삭제돼요. 완전 편리하죠? 😎
💡 Pro Tip: 재능넷 같은 대규모 플랫폼에서는 로그 양이 엄청나게 많을 거예요. 이런 경우에는 로그를 여러 파일로 분리하는 것이 좋아요. 예를 들어, 에러 로그, 사용자 활동 로그, 시스템 로그 등으로 나눌 수 있죠. 각각에 대해 별도의 애펜더를 설정하면 돼요!
자, 이제 로그 파일 관리의 기본을 배웠어요. 하지만 여기서 끝이 아니에요! 더 고급 기능들이 기다리고 있답니다. 예를 들어, 비동기 로깅을 사용하면 로깅으로 인한 애플리케이션의 성능 저하를 최소화할 수 있어요. 한번 살펴볼까요? 🚀
<configuration>
<!-- 기존 FILE 애펜더 설정 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
</appender>
<root level="INFO">
<appender-ref ref="ASYNC" />
</root>
</configuration>
이렇게 AsyncAppender를 사용하면, 로그 메시지가 먼저 메모리 큐에 저장되고, 별도의 스레드에서 파일에 기록돼요. 덕분에 애플리케이션의 주 스레드는 로깅 작업으로 인해 블로킹되지 않아요. 성능 향상의 마법이죠! ✨
그리고 또 하나! 로그 파일을 압축하는 것도 잊지 마세요. 로그 파일은 보통 텍스트라 압축률이 높아요. gzip으로 압축하면 저장 공간을 크게 절약할 수 있죠. 위의 설정에서 이미 .gz
확장자를 사용해 자동 압축을 적용했어요.
🎓 Advanced Tip: 대규모 시스템에서는 로그를 중앙 집중식으로 관리하는 것이 좋아요. ELK 스택(Elasticsearch, Logstash, Kibana)이나 Splunk 같은 도구를 사용하면 여러 서버의 로그를 한 곳에서 모아보고 분석할 수 있어요. Logback에서는 SocketAppender를 사용해 이런 시스템으로 로그를 전송할 수 있답니다!
자, 이제 여러분은 로그 파일 관리의 달인이 되었어요! 🏆 파일 애펜더와 로그 로테이션, 비동기 로깅까지 마스터했으니 이제 어떤 상황에서도 로그 관리를 완벽하게 할 수 있을 거예요. 재능넷 같은 대규모 플랫폼에서도 문제없이 로그를 관리할 수 있겠죠?
다음 섹션에서는 로그 필터링과 마스킹에 대해 알아볼 거예요. 민감한 정보를 어떻게 보호하면서 로깅할 수 있을지, 함께 살펴보아요! 준비되셨나요? Let's go! 🚀
🕵️♀️ 비밀 요원의 필수 스킬: 로그 필터링과 마스킹
자, 이제 우리는 로그를 어디에 어떻게 저장할지 알게 되었어요. 하지만 잠깐, 여기서 중요한 문제가 하나 있어요. 바로 민감한 정보를 어떻게 다룰 것인가 하는 거죠. 🤫
재능넷 같은 플랫폼에서는 사용자의 개인정보, 결제 정보 등 민감한 데이터를 다루게 될 거예요. 이런 정보가 그대로 로그에 남는다면? 큰일 나겠죠! 😱 그래서 우리에겐 로그 필터링과 마스킹 기술이 필요해요.
Logback에서는 필터를 사용해 특정 로그를 제외하거나, 컨버터를 사용해 특정 패턴의 데이터를 마스킹할 수 있어요. 어떻게 하는지 살펴볼까요? 🧐
1. 로그 필터링
먼저, 특정 패턴의 로그를 아예 기록하지 않도록 필터링해볼게요. 예를 들어, 비밀번호가 포함된 로그는 모두 제외하고 싶다면 이렇게 할 수 있어요:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>return message.contains("password");</expression>
</evaluator>
<OnMatch>DENY</OnMatch>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
이 설정은 "password"라는 단어가 포함된 모든 로그 메시지를 무시해요. 완전 비밀 요원 스타일이죠? 😎
2. 데이터 마스킹
때로는 로그를 완전히 제외하는 대신, 민감한 부분만 가리고 싶을 수 있어요. 이럴 때는 컨버터를 사용하면 돼요. 예를 들어, 이메일 주소의 일부를 가리고 싶다면:
<configuration>
<conversionRule conversionWord="maskedMsg"
converterClass="com.example.log.MaskingConverter" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %maskedMsg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
여기서 MaskingConverter
는 직접 구현해야 하는 클래스예요. 이렇게 구현할 수 있죠:
import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
public class MaskingConverter extends MessageConverter {
private static final String EMAIL_REGEX = "(\\w+)(\\.\\w+)*@(\\w+\\.)(\\w+)(\\.\\w+)*";
private static final String MASK = "$1****@$3$4";
@Override
public String convert(ILoggingEvent event) {
String message = event.getFormattedMessage();
return message.replaceAll(EMAIL_REGEX, MASK);
}
}
이 컨버터는 이메일 주소의 로컬 파트(@ 앞부분)를 마스킹해요. 예를 들어, "user.name@example.com"은 "user****@example.com"으로 변환되죠.
💡 Pro Tip: 마스킹 규칙은 회사의 보안 정책에 따라 다를 수 있어요. 신용카드 번호, 주민등록번호 등 다양한 형태의 민감 정보에 대해 각각 다른 마스킹 규칙을 적용할 수 있답니다. 정규표현식을 잘 활용하면 거의 모든 형태의 데이터를 마스킹할 수 있어요!
이렇게 필터링과 마스킹을 적용하면, 로그에서 민감한 정보를 안전하게 보호할 수 있어요. 재능넷 같은 플랫폼에서는 사용자의 개인정보 보호가 정말 중요하니까, 이런 기술은 필수겠죠?
하지만 주의하세요! 로그 필터링과 마스킹을 너무 과도하게 적용하면 필요한 정보까지 놓칠 수 있어요. 항상 보안과 유용성 사이의 균형을 잘 맞추는 게 중요해요. 😉
자, 이제 여러분은 진정한 로그 닌자가 되었어요! 🥷 로그를 생성하고, 저장하고, 관리하고, 심지어 민감한 정보도 보호할 수 있게 되었으니까요. 이제 마지막으로, 모든 것을 종합해서 실제 운영 환경에 적용하는 방법에 대해 알아볼까요? 준비되셨나요? 마지막 스퍼트 한번 해봐요! 💪
🏁 실전 적용: 완벽한 Logback 설정의 정점
드디어 마지막 단계에 도달했어요! 🎉 지금까지 배운 모든 것을 종합해서, 실제 운영 환경에서 사용할 수 있는 완벽한 Logback 설정을 만들어볼 거예요. 재능넷 같은 대규모 플랫폼에 적용할 수 있는 수준의 설정이 될 거예요. 준비되셨나요? 😎
먼저, 우리의 최종 logback-spring.xml
파일을 살펴볼게요:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="./logs" />
<property name="LOG_FILE_NAME" value="myapp" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%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}.%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
</appender>
<conversionRule conversionWord="maskedMsg"
converterClass="com.example.log.MaskingConverter" />
<logger name="com.example.myapp" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC" />
</logger>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC" />
</root>
</configuration>
우와, 정말 완벽한 설정이죠? 😍 이 설정이 어떤 일을 하는지 하나씩 살펴볼게요:
- 콘솔과 파일 두 가지 방식으로 로그를 출력해요.
- 파일 로그는 날짜별, 크기별로 롤링되며, 압축 저장돼요.
- 비동기 로깅을 사용해 성능을 최적화했어요.
- 커스텀 마스킹 컨버터를 적용해 민감 정보를 보호해요.
- 애플리케이션 패키지는 DEBUG 레벨로, 그 외는 INFO 레벨로 로깅해요.
이 설정을 사용하면, 개발 시에는 콘솔에서 상세한 로그를 확인할 수 있고, 운영 환경에서는 파일로 안전하게 로그를 저장할 수 있어요. 게다가 민감 정보도 자동으로 마스킹되니 보안도 완벽하죠!
💡 Pro Tip: 실제 운영 환경에서는 로그 레벨을 동적으로 변경할 수 있도록 설정하는 것이 좋아요. Spring Boot Actuator를 사용하면 런타임에 로그 레벨을 변경할 수 있답니다. 문제 상황이 발생했을 때 매우 유용해요!
자, 이제 정말 완벽한 Logback 설정이 완성됐어요. 이 설정을 사용하면 재능넷 같은 대규모 플랫폼에서도 로그 관리를 완벽하게 할 수 있을 거예요. 로그 생성부터 저장, 관리, 보안까지 모든 것을 커버했으니까요! 👍
마지막으로, 로깅은 단순히 기술적인 문제가 아니라는 점을 기억하세요. 좋은 로깅 전략은 개발 생산성을 높이고, 문제 해결 시간을 단축시키며, 시스템의 안정성을 높여줘요. 여러분의 로깅 전략이 이 모든 것을 달성할 수 있기를 바랄게요! 🌟
여기까지 긴 여정을 함께 해주셔서 정말 감사해요. 이제 여러분은 Logback 마스터가 되었어요! 🏆 앞으로 여러분의 프로젝트에서 로깅 문제로 고민하는 일은 없을 거예요. 화이팅! 💪😄