어떤 플랫폼을 실행하든 로깅은 종종 빅데이터 처리, 통계, 감사, 클라이언트 보고서 및 거래에 대한 핵심 요구 사항일 뿐만 아니라 클라이언트-서버 통신 및 발생 가능한 문제를 디버깅하는 데에도 핵심 요구 사항입니다.
이 블로그에서는 디버깅에서 로깅의 역할에 대해 살펴보겠습니다. 로깅은 인터넷 통신에서 흔히 발생하는 다양한 문제를 찾아내는 최고의 도구입니다.
클라이언트-웹 서버 통신을 로깅하면 브라우저 버전, 클라이언트의 네트워크, 액세스하는 파일과 관련된 잠재적인 문제를 디버깅하는 데 큰 도움이 됩니다. 하지만 거기서 끝나지는 않습니다. 무엇을 기록할지는 전적으로 플랫폼과 요구 사항에 따라 달라집니다.
역방향 프록시, 로드 밸런서 또는 콘텐츠 전송 네트워크(CDN)를 실행하면 클라이언트와 서버 간 통신 흐름에 또 다른 노드가 추가됩니다. 역방향 프록시처럼 데이터를 조작하는 중간 서버는 종종 예상치 못한 문제를 야기합니다.
역방향 프록시로서, NGINX는 클라이언트에서 웹 서버(또는 다른 앱 서버)로의 연결을 두 개의 별도 연결로 변환합니다. 즉, 클라이언트에서의 연결을 종료하고 서버로의 새 연결을 만듭니다. 두 개의 연결로 "분할"하면 로깅을 위한 두 개의 별도 컨텍스트가 생성되고 NGINX는 이에 대한 로깅을 다소 다르게 지원합니다.
클라이언트와 역방향 프록시 간 트래픽에 대해 NGINX는 오류 로그 와 액세스 로그를 모두 제공하며, 이는 오류가 아닌 처리 이벤트와 동작을 기록합니다.
error_log
지시어로 오류 로그를 활성화하고, 기록할 오류의 심각도 수준을 설정할 수 있습니다.
access_log
지시문을 사용하여 액세스 로그를 활성화합니다. 연관된 log_format
지시어를 사용하면 로그에 포함되는 정보 종류와 로그 항목의 형식을 사용자 정의할 수 있습니다. 로그를 파일이나 syslog에 기록할 수도 있고, 둘 다에 기록할 수도 있습니다.
역방향 프록시와 웹 또는 앱 서버(NGINX에서는 업스트림 서버 라고 함) 간의 트래픽에 대해 NGINX는 오류 로그를 지원합니다. 하지만 이 트래픽에 대한 액세스 로깅은 지원하지 않습니다.
프록시 서버와 업스트림 서버 간의 오류가 아닌 이벤트를 확인하는 유일한 방법은 오류 로그의 심각도 수준을 디버그
로 설정하는 것입니다. 이 설정의 단점은 엄청난 양의 데이터가 기록된다는 것입니다. 이로 인해 요청 처리 속도가 느려지고, 매우 큰 파일이 생성되어 저장소가 금세 가득 찰 수 있습니다. (디버깅 지원은 기본적으로 활성화되어 있지 않으므로 configure
명령에서 --with-debug
인수를 사용하여 NGINX를 다시 컴파일해야 합니다.)
CDN 공급업체로서 저희는 종종 역방향 프록시 서버 및 클라이언트와 제대로 통신하지 못하는 업스트림 서버에 부딪힙니다. 오류 로그의 디버그
수준 메시지는 항상 업스트림 서버의 문제를 해결하는 데 필요한 종류의 정보를 제공하지 않습니다.
해결책은 곧 명확해졌습니다. 역방향 프록시와 업스트림 서버 간의 통신에서 필수 정보만 수집하는 기능을 추가하여 업스트림 액세스 로그를 생성하는 것입니다.
전체적인 아이디어는 업스트림 서버에 대한 요청이 있을 때마다 NGINX가 우리 함수를 호출하는 것입니다. 이를 통해 업스트림 로깅과 관련된 모든 로직을 함수 자체에서 프로그래밍할 수 있습니다.
표준 ngx_http_upstream_module은
업스트림 요청을 처리하고, 이를 통해 함수를 호출해야 합니다. 현재 모듈은 이러한 기능을 지원하지 않으므로 필요할 때 콜백을 활성화하도록 패치했습니다.
로깅 자체는 우리가 패치한 업스트림 모듈에 추가한 로그 콜백 기능을 사용하는 별도의 모듈에서 처리됩니다. 새로운 모듈은 로깅 기능을 구성하기 위한 새로운 upstream_log
지시문을 정의합니다. 이 지시어는 access_log
지시어와 동일한 파서를 사용하므로, 데이터를 파일에 기록하거나 소켓을 사용하여 syslog 서버로 전송할 수 있습니다.
NGINX가 시작 중에 nginx.conf 에서 upstream_log
지시문을 읽으면 두 개의 함수가 호출됩니다.
ngx_http_upstream_log_set_log
는 지시문을 구문 분석하고 내부적으로 ngx_log_set_log를
사용하여 로그 구조 자체( ngx_log_t
)를 준비합니다.ngx_http_upstream_log_init
(구성 후 단계)는 업스트림 모듈에 주 로깅 기능을 등록합니다.이렇게 하면 요청을 업스트림으로 프록시해야 할 때 모든 것이 준비됩니다. 업스트림 모듈은 업스트림 서버로의 연결을 시작하고, 우리 패치는 로깅 함수가 호출되어 요청 세부 정보를 기록하도록 합니다.
로그 형식은 업스트림 모듈에 하드와이어되어 있습니다. log_format
지시어를 사용하여 구성에 대한 지원을 추가하는 옵션도 있지만, 우리의 사용 사례에서는 반드시 필요한 것은 아닙니다.
로깅 기능은 업스트림 서버와의 연결이 닫히자마자 호출됩니다. 해당 인수는 현재 처리된 요청( ngx_http_request_t
구조체)에 대한 포인터이며, 이를 통해 함수는 구조체의 모든 데이터에 액세스하고 기록할 수 있습니다. 업스트림
필드( ngx_http_upstream_t를
가리키는 포인터)는 업스트림 요청에 대한 데이터를 담고 있으므로 특히 중요합니다. 우리는 특히 다음 사항에 관심이 있습니다.
전체 요청 구조에 액세스할 수 있다는 것은 모듈에 유연성을 제공하는데, 다양한 정보를 기록할 수 있기 때문입니다.
우리는 처음에 ngx_http_core_module
에서 해당 기능을 구현했습니다. 이는 프로토타입으로는 충분하지만, 향후 업데이트와 수정을 복잡하게 만들 수 있어 그다지 깔끔한 솔루션은 아니었습니다. 결국, 우리는 업스트림 로깅 솔루션 에 설명된 대로 업스트림 로깅 기능을 독립 실행형 모듈로 분리했습니다.
물론, 구현상의 몇 가지 문제도 있었습니다. 특히, 일부 부분에서는 ngx_str_t
문자열을 잘못 처리했습니다. 예를 들어, ngx_snprintf
대신 C 라이브러리 함수 sprintf를
사용했습니다. 이로 인해 정의되지 않은 데이터가 업스트림 로그에 기록되거나 작업자 스레드에서 세그먼테이션 오류가 발생할 수도 있습니다. 이러한 문제는 Valgrind와 AddressSanitizer와 같은 도구를 사용하여 광범위한 디버깅과 테스트를 거친 후 해결되었습니다.
CDN77이 NGINX를 사용하는 주된 이유는 캐싱 기능 때문입니다. CDN 서버는 클라이언트와 웹 서버(업스트림 서버) 사이에 도입된 노드로, 클라이언트 요청을 전달하고 업스트림 서버에 적절한 파일을 요청합니다. 파일이 캐시되면 같은 위치에서 같은 파일을 요청하는 다른 사용자에게 전달됩니다.
"로컬로 제공된 파일"은 NGINX가 요청을 받을 때 서버의 디스크에서 파일을 제공하는 데 사용하는 기능 중 하나입니다.
보안 캐싱을 위해서는 몇 가지 추가 기능과 구성이 필요합니다. 우리는 콘텐츠를 적절하게 보호하기 위해 특정 IP 주소에 대해 생성될 수 있는 SSL(0‑RTT가 있는 TLS 1.3) 또는 보안 토큰을 활용합니다.
우리가 사용하는 다른 기능으로는 클라이언트를 위한 맞춤형 오류 페이지, OCSP 스테이플링의 기본 NGINX 구현, 필요한 PHP 프로세스 수를 줄이기 위한 PHP용 FastCGI가 있습니다.
업스트림 로깅은 다양한 문제를 디버깅하는 데 도움이 되었을 뿐만 아니라, NGINX의 핵심 기능을 더 자세히 살펴보고 우리가 수행한 수많은 다른 프로젝트를 단순화할 수 있는 훌륭한 기회도 제공했습니다.
CDN77은 전 세계적으로 콘텐츠 전송을 더욱 편리하고 개선합니다. 30개가 넘는 데이터 센터를 통해 우리는 전 세계적으로 콘텐츠를 효과적으로 캐싱하고 전송할 수 있습니다. 여기에는 웹사이트의 정적 콘텐츠, 소프트웨어 배포, 주문형 비디오(VoD), 전용 스트리밍 엔진을 사용한 HLS나 MPEG‑DASH와 같은 다양한 프로토콜을 통한 라이브 스트리밍이 포함됩니다.
CDN77을 시작하는 것은 매우 쉽고 빠르며 간단합니다. 무료 평가판 에 가입하고 CDN 리소스를 만들고 생성된 CDN URL이나 사용자 정의 CNAME
레코드를 사용하여 귀하의 웹사이트나 스트리밍 솔루션과 통합하세요. 모든 기능, 설정 및 가능한 사용자 정의 솔루션을 통해 CDN77은 귀하의 요구 사항을 충족합니다.
"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."