본문 바로가기
Java/트러블 슈팅

Nginx와 WAS의 로깅 식별자(request_id) 공유하기

by oneny 2023. 12. 17.

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로 로깅 식별자 적용하기

로깅 로깅은 프로그램 동작 시 발생하는 모든 일(서비스 동작 상태 및 장애)을 기록하는 행위를 말한다. 이를 통해 개발, 테스트, 운영 등 다양한 환경에서 애플리케이션의 동작을 이해하고 모니

oneny.tistory.com

이전 게시글에서는 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 log 파일
was log 파일

Nginx에서 제공하는 $request_id 변수값을 사용하여 Nginx 로그 파일에서도 WAS 로그 파일에서도 모두 같은 식별자가 로깅되는 것을 확인할 수 있다.

 

 

출처

NGINX $request_id 변수로 애플리케이션 추적하기

[Spring] 멀티쓰레드 환경에서 MDC를 사용해 요청 별로 식별 가능한 로그 남기기