java
CHAPTER 86 / 99
읽기 약 2분
FUNCTION
로깅 전략: SLF4J + Logback
핵심 개념
로그 레벨·MDC·JSON 포맷·ELK Stack — 프로덕션 로그 분석.
본문
SLF4J + Logback 기본
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserService {
private static final Logger log = LoggerFactory.getLogger(UserService.class);
// Lombok @Slf4j 사용 시 위 코드 자동
public User signup(SignupDto dto) {
log.debug("Signup attempt: {}", dto.email());
try {
User user = userRepo.save(new User(dto));
log.info("User signed up: id={}, email={}", user.getId(), user.getEmail());
return user;
} catch (DuplicateEmailException e) {
log.warn("Duplicate email: {}", dto.email());
throw e;
} catch (Exception e) {
log.error("Signup failed for {}: {}", dto.email(), e.getMessage(), e);
throw e;
}
}
}로그 레벨 가이드
TRACE: 매우 상세 — 개발만 (보통 비활성)
DEBUG: 진단 — 개발/스테이징
INFO: 일반 — 프로덕션 기본
WARN: 비정상이지만 복구 가능
ERROR: 에러 + 즉시 대응 필요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>
<!-- 파일 — 일별 롤링 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- JSON 포맷 — ELK용 -->
<appender name="JSON" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.json</file>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"service":"ohs-api","env":"prod"}</customFields>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
</rollingPolicy>
</appender>
<springProfile name="dev">
<root level="DEBUG"><appender-ref ref="CONSOLE"/></root>
</springProfile>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="JSON"/>
</root>
</springProfile>
</configuration>MDC — 요청 추적
@Component
public class RequestLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws ServletException, IOException {
String requestId = req.getHeader("X-Request-Id");
if (requestId == null) requestId = UUID.randomUUID().toString();
MDC.put("requestId", requestId);
MDC.put("path", req.getRequestURI());
MDC.put("method", req.getMethod());
try {
chain.doFilter(req, res);
} finally {
MDC.clear();
}
}
}
// 로그 패턴에 MDC 포함
// %d{ISO8601} [%X{requestId}] %-5level %logger - %msg%nELK Stack 통합
앱 → JSON 로그 → Filebeat → Logstash → Elasticsearch → Kibana
조회 예:
- 특정 사용자의 모든 액션
- 에러 폭주 시간대 분석
- API별 P95 응답 시간
- 트래픽 급증 패턴다음 챕터
CH.18 "프로파일 관리: application.yml" — 환경별 설정.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 Spring 코드의 로깅 전략 부분을 분석해서 로그 품질·검색성와 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
로깅 전략 vs 다른 패턴 비교를 실전 사례 5개로 보여주고 JSON 로그 vs Plain text를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 코드베이스 전체를 분석해서 로깅 전략 관련 민감 정보 누출 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 기업의 로깅 전략 채택률과 한국 SaaS의 로그 인프라를 솔직히 알려줘.
⭐ 이것만 기억하세요
로깅 전략: SLF4J + Logback는 이 3가지만 확실히 잡으세요
1.SLF4J + Logback이 Java 로깅 표준 — 인터페이스(SLF4J) + 구현(Logback) 분리
2.MDC로 요청 컨텍스트 추가 + JSON 포맷으로 ELK 통합 = 프로덕션 디버깅 표준
3.다음 챕터 CH.18에서 환경별 설정 — dev/staging/prod 분리
공유하기
진행도 86 / 99