기본 Combined Log Format은 범용적이지만, 특정 분석 목적에 맞춘 커스텀 로그 포맷이 더 효율적일 수 있습니다. 불필요한 필드를 제거하고 필요한 데이터만 로깅하는 방법을 알아봅니다.
`` 192.0.2.100 - - [10/Oct/2024:14:00:00 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0" `
: 거의 항상 하이픈 (사용 안 함) (공간 낭비)`nginx log_format security '$remote_addr [$time_local] "$request" $status "$http_user_agent" "$request_body"'; `
`nginx log_format performance '$time_local $request_time $upstream_response_time "$request" $status $body_bytes_sent'; `
`nginx log_format traffic '$remote_addr $request_method $uri $status $body_bytes_sent "$http_referer"'; `
`nginx log_format cache '$time_local "$request" $status $upstream_cache_status $body_bytes_sent'; `
파싱이 쉽고 ELK 스택과 호환:
`nginx log_format json escape=json '{' '"time":"$time_iso8601",' '"remote_addr":"$remote_addr",' '"request":"$request",' '"status":$status,' '"body_bytes_sent":$body_bytes_sent,' '"request_time":$request_time,' '"http_user_agent":"$http_user_agent"' '}'; `
로그 예시:
`json {"time":"2024-10-10T14:00:00+00:00","remote_addr":"192.0.2.100","request":"GET / HTTP/1.1","status":200,"body_bytes_sent":1234,"request_time":0.312,"http_user_agent":"Mozilla/5.0"} `
`nginx map $status $loggable { ~^[23] 0; default 1; }
access_log /var/log/nginx/access.log combined if=$loggable; `
200/300번대는 로깅 안 함 → 로그 크기 80% 감소
`nginx location ~* \.(jpg|png|css|js)$ { access_log off; } `
`nginx map $remote_addr $log_internal { 192.168.1.0/24 0; default 1; }
access_log /var/log/nginx/access.log combined if=$log_internal; `
느린 요청만 별도 로그:
`nginx map $request_time $slow_request { ~^[01]\. 0; # 1초 미만 default 1; }
access_log /var/log/nginx/access.log combined; access_log /var/log/nginx/slow.log combined if=$slow_request; `
중앙 로그 서버로 실시간 전송:
`nginx access_log syslog:server=10.0.0.1:514,tag=nginx combined; `
| 변수 | 의미 |
|---|---|
| ------ | ------ |
$request | 전체 요청 라인 |
$request_method | GET, POST 등 |
$request_uri | 전체 URI + 쿼리 |
$uri | 경로만 (쿼리 제외) |
$args | 쿼리 문자열만 |
$request_body | POST 바디 |
| 변수 | 의미 |
| ------ | ------ |
$status | HTTP 상태 코드 |
$body_bytes_sent | 응답 바이트 |
$bytes_sent | 헤더 포함 전체 바이트 |
| 변수 | 의미 |
| ------ | ------ |
$time_local | 로컬 시각 |
$time_iso8601 | ISO 8601 형식 |
$msec | UNIX 타임스탬프 (밀리초) |
$request_time | 총 요청 처리 시간 |
| 변수 | 의미 |
| ------ | ------ |
$remote_addr | 클라이언트 IP |
$http_user_agent | User-Agent |
$http_referer | Referer |
$http_x_forwarded_for | 프록시 경유 실제 IP |
| 변수 | 의미 |
| ------ | ------ |
$upstream_addr | 백엔드 서버 주소 |
$upstream_response_time | 백엔드 응답 시간 |
$upstream_status | 백엔드 상태 코드 |
$upstream_cache_status | 캐시 상태 |
설정 변경 후 테스트:
`bash sudo nginx -t sudo systemctl reload nginx curl http://localhost/ tail -1 /var/log/nginx/access.log ``
기본 Combined Format은 범용적이지만, 분석 목적에 맞춘 커스텀 포맷이 더 효율적입니다. 불필요한 필드를 제거하고, 조건부 로깅으로 로그 크기를 줄이세요. JSON 포맷은 자동화 분석에 유리합니다.