로그관리와 모니터링 - ELK 프로메테우스 그라파나편
tracking-requests-with-mdc-logging-filter
✅ 1. MDC 필터를 만드는 이유
- 웨이팅 API에서 100명의 손님이 동시에 웨이팅을 건다면 어떨까?
- 여러 로그들이 섞이며 로그가 복잡해지고, 에러 발생시 찾기 어려워진다.
- 서버에 들어오는 모든 요청에 대해 대기번호(Trace ID)를 붙여줄 수 있게 필터를 만들어보자.
- 이때 발급받은 대기번호를 담아두는 주머니가 바로 MDC(Mapped Diagnostic Context)이다.
- 각각의 요청(스레드)이 끝날 때까지 고유한 상태를 기억해 놓는 것이 특징
✅ 2. 필터 생성
MdcLoggingFilter.java
package com.hi.waiting_api;
import jakarta.servlet.*;
@Component
public class MdcLoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 1. 요청이 들어오면 고유한 8글자 Trace ID를 생성
String traceId = UUID.randomUUID().toString().substring(0, 8);
// 2. MDC라는 곳에 해당 아이디를 보관
MDC.put("traceId", traceId);
try {
// 3.Controller로 요청을 넘김.
chain.doFilter(request, response);
} finally {
// 요청 처리가 끝나면 반드시 비워줘야 함
// 톰캣은 재사용되기 때문에, 안 비우면 다음 사람 로그에 이전 사람 ID가 섞일 수 있음
MDC.clear();
}
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
✅ 3. Controller 수정
WaitingController.java
package com.hi.waiting_api;
@RestController
@RequestMapping("/api/waiting")
@RequiredArgsConstructor
@Slf4j
public class WaitingController {
private final WaitingService waitingService;
@PostMapping
public String register(@RequestBody WaitingRequest request) {
try {
log.info("[api 호출] 웨이팅 등록 요청 들어옴");
return waitingService.registerWaiting(request.getName(), request.getPhone());
} catch (IllegalArgumentException e) {
log.error("[api 오류] 웨이팅 등록 중 문제 발생 : {}", e) ;
return "웨이팅 등록에 실패했습니다: " + e.getMessage();
}
}
}
✅ 4. 로그 확인
✅ 5. Logback 설정 파일 생성
logback-spring.xml
흑백버전
컬러버전
6. 로그에서 UUID 확인