Nginx 액세스 로그: 각 필드의 의미와 분석 방법
Nginx 액세스 로그는 웹 서버가 처리하는 모든 요청을 기록합니다. 404 오류를 디버깅하거나 느린 엔드포인트를 추적하거나 의심스러운 트래픽을 조사할 때 가장 먼저 확인해야 할 곳입니다. 하지만 많은 개발자가 각 필드를 완전히 이해하지 않은 채 원시 로그 줄을 대충 훑어봅니다. 이 가이드에서는 기본 Nginx 로그 형식을 분석하고, 사용자 정의하는 방법을 보여주며, 표준 명령줄 도구를 사용한 실용적인 분석 기법을 안내합니다.
기본 Nginx 액세스 로그 형식
기본적으로 Nginx는 combined 로그 형식을 사용하며, 다음과 같습니다:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
일반적인 로그 줄:
192.0.2.1 - - [10/Oct/2023:13:55:36 +0000] "GET /api/users HTTP/1.1" 200 1234 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
필드별 설명
| 필드 | 변수 | 설명 |
|---|---|---|
| 원격 주소 | $remote_addr | 요청을 보낸 클라이언트의 IP 주소. |
| 원격 사용자 | $remote_user | HTTP 인증이 사용된 경우 사용자 이름, 그렇지 않으면 -. |
| 로컬 시간 | $time_local | [일/월/년:시:분:초 존] 형식의 서버 로컬 시간. |
| 요청 | $request | 전체 요청 줄: 메서드, 경로, HTTP 프로토콜. |
| 상태 | $status | HTTP 응답 상태 코드 (예: 200, 404, 500). |
| 전송된 본문 바이트 | $body_bytes_sent | 헤더를 제외한 응답 본문의 크기(바이트). |
| 리퍼러 | $http_referer | 요청을 링크한 페이지 (클라이언트가 제공한 경우). |
| 사용자 에이전트 | $http_user_agent | 클라이언트 소프트웨어 문자열 (브라우저, 봇, 도구). |
로그 형식 사용자 정의
요청 시간, 업스트림 응답 시간, gzip 비율 등 추가 세부 정보를 캡처하도록 자체 형식을 정의할 수 있습니다. http 블록에 log_format 지시문을 추가하고 access_log에서 참조하세요.
http {
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log detailed;
}
자주 사용되는 추가 변수:
$request_time– 첫 바이트 수신부터 마지막 바이트 전송까지의 총 시간.$upstream_response_time– 업스트림 (예: PHP-FPM, Node.js) 대기 시간.$gzip_ratio– gzip이 활성화된 경우 압축 비율.$http_x_forwarded_for– 프록시 또는 로드 밸런서 뒤에 있을 때 원래 클라이언트 IP.
명령줄 도구로 Nginx 로그 분석하기
인사이트를 얻기 위해 비싼 소프트웨어가 필요하지 않습니다. grep, awk, sort, uniq 같은 표준 Unix 도구만으로도 대부분의 작업에 충분합니다.
1. 가장 빈번한 IP 주소 찾기
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
이를 통해 트래픽이 많은 소스나 잠재적인 DDoS 공격 소스를 식별할 수 있습니다.
2. 가장 많이 요청된 URL 확인
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
인기 콘텐츠를 파악하거나 비정상적인 패턴을 발견하는 데 유용합니다.
3. HTTP 상태 코드 개수 세기
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
404 또는 500 오류가 얼마나 발생하는지 빠르게 확인할 수 있습니다.
4. 응답 시간이 느린 요청 찾기
로그 형식에 $request_time을 추가했다면 느린 요청을 필터링할 수 있습니다:
awk '{ if ($NF > 1) print }' /var/log/nginx/access.log
필요에 따라 임계값(여기서는 1초)을 조정하세요.
5. 의심스러운 사용자 에이전트 탐지
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
알려진 악성 봇이나 비정상적인 클라이언트를 찾아보세요.
실용적인 사용 사례
- 문제 해결: 500 오류를 특정 엔드포인트나 업스트림 응답 시간과 연관시키세요.
- 성능 튜닝: 느린 페이지를 식별하고 데이터베이스 쿼리나 캐싱을 최적화하세요.
- 보안 모니터링: 무차별 대입 시도(동일 IP에서 많은 401/403)나 URL의 SQL 인젝션 패턴을 발견하세요.
- 용량 계획: 시간 경과에 따른 요청량을 추적하여 확장 필요성을 예측하세요.
로그 파서로 분석 자동화하기
명령줄 원라이너는 임시 쿼리에 유용하지만, 정기적인 보고에는 전용 도구가 더 적합합니다. GoAccess나 AWStats 같은 오픈소스 로그 분석기를 사용하거나 사용자 정의 스크립트를 작성할 수 있습니다. 아무것도 설치하지 않고 브라우저 기반으로 빠르게 파싱하려면 Nginx Log Analyzer를 사용하여 로그 줄을 붙여넣고 상태 코드, 상위 IP, 요청 경로에 대한 즉각적인 요약을 얻을 수 있습니다.
로그 관리 모범 사례
- 정기적으로 로그 순환:
logrotate를 사용하여 디스크 공간 문제를 방지하세요. - 로그 중앙화: 장기 저장 및 검색을 위해 로그 관리 시스템(예: ELK, Graylog)으로 전송하세요.
- 요청 ID 포함: 애플리케이션 로그와 연관시키려면
$request_id를 추가하세요. - 개인정보 보호: GDPR 또는 기타 규정에 따라 필요한 경우 IP를 익명화하세요.
자주 묻는 질문
Nginx에서 액세스 로그와 에러 로그의 차이점은 무엇인가요?
액세스 로그는 클라이언트 IP, 요청 메서드, 상태 코드, 사용자 에이전트를 포함하여 Nginx가 처리한 모든 요청을 기록합니다. 에러 로그는 연결 실패, 구성 오류, 업스트림 타임아웃 등 서버 문제에 대한 진단 메시지를 캡처합니다. 두 로그 모두 다양한 문제 해결 시나리오에 필수적입니다.
Nginx가 로드 밸런서 뒤에 있을 때 실제 클라이언트 IP를 어떻게 확인할 수 있나요?
Nginx가 프록시나 로드 밸런서 뒤에 있으면 $remote_addr은 밸런서의 IP를 표시합니다. 원래 클라이언트 IP를 기록하려면 real_ip 모듈을 구성하여 밸런서의 IP를 신뢰하고 로그 형식에 $http_x_forwarded_for 또는 $realip_remote_addr을 사용하세요.
소프트웨어를 설치하지 않고 Nginx 로그를 분석할 수 있나요?
네. 터미널에서 grep, awk, sort 같은 표준 Unix 명령을 직접 사용할 수 있습니다. 그래픽 브라우저 기반 접근 방식을 원한다면 Nginx Log Analyzer 같은 온라인 도구가 설치 없이 빠른 인사이트를 제공합니다.
로그 분석을 시작할 준비가 되셨나요? Nginx Log Analyzer를 사용하여 몇 초 만에 액세스 로그를 파싱하고 시각화하세요—설정이 필요 없습니다.