Nginx와 WAS의 로깅 식별자(request_id) 공유하기
현재 프로젝트의 서비스 환경은 위 그림과 같다. WAS만 사용하는 것이 아니라 Nginx와 같은 Web Server를 앞단에 두고 사용하고 있다. 따라서 Nginx 로그와 WAS 로그를 함께 봐야하는 경우가 많은데, 이때 Nginx와 WAS가 동일한 request_id를 공유하면 로그 파악이 매우 용이해진다.
Nginx 설정
Nginx에서는 제공하는 변수 중 하나로 $request_id가 있다. 이 변수는 각 HTTP 요청에 대해 고유한 식별자를 생성하여 주로 로깅이나 디버깅 목적으로 사용된다. 이 변수는 ngx_http_core_module 모듈에서 제공되며 32개의 16진수 문자열로 각 HTTP 요청이 도착하면 자동으로 할당된다.
이전 게시글에서는 Logback과 MDCFilter를 사용하여 WAS에 HTTP 요청에 대한 고유한 요청 ID를 생성하고 로그에 포함시키도록 구현했다. 하지만 이는 위에서도 말했듯이 Nginx와 같은 Web Server를 앞단에 두면 Web Server와 WAS 로그를 모두 확인하는 경우가 많기 때문에 $request_id 값을 전달하도록 Web Server와 WAS를 구성하면 모든 요청을 종단간 추적할 수 있다.
요청 추적을 위해 Nginx를 먼저 구성하기 위해서는 Nginx 설정 파일에서 upstream 블록에서 정의한 어플리케이션 서버 중 하나로 네트워크 요청을 보내기 전에 proxy_set_header 지시문을 사용하여 X-Request-ID라는 새 헤더를 만들고 $request_id 변수의 값을 할당하여 요청을 프록시하도록 수정했다.
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" "$request_id"';
access_log /path/to/access.log main;
그리고 위처럼 로그 포맷을 $request_id 변수도 같이 로깅하도록 작성하면 주어진 경로에 있는 access.log 파일에 $request_id도 같이 로그로 남는 것을 확인할 수 있다. 이는 마지막에 확인해보자.
MDCFilter 수정
그리고 MDCFilter를 위처럼 수정했는데 request.getHeader("X-Request-ID")를 통해 HTTP 헤더에서 "X-Request-ID" 헤더 값을 읽어오는 것을 확인할 수 있다. 그리고 MDC에 request_id라는 키로 값을 추가하고 만약 "X-Request-ID" 헤더가 존재하지 않으면 랜덤한 UUID가 생성되어 사용되도록 수정했다.
적용 결과
Nginx에서 제공하는 $request_id 변수값을 사용하여 Nginx 로그 파일에서도 WAS 로그 파일에서도 모두 같은 식별자가 로깅되는 것을 확인할 수 있다.
출처
NGINX $request_id 변수로 애플리케이션 추적하기
[Spring] 멀티쓰레드 환경에서 MDC를 사용해 요청 별로 식별 가능한 로그 남기기
'Java > 트러블 슈팅' 카테고리의 다른 글
페이징 성능 개선: offset vs no offset vs covering index (0) | 2023.12.25 |
---|---|
synchronized vs Pessimistic Lock vs Distributed Lock (1) | 2023.12.21 |
Blue/Green 방식으로 서비스 중단없이 배포하기 (1) | 2023.12.17 |
Jenkins으로 CI/CD 구축하기 (0) | 2023.12.09 |
세션은 어느 계층에서 처리해야 할까? (3) | 2023.11.30 |