← 블로그 목록
작성일: 2026-06-03 로그 포맷NginxJSON

커스텀 로그 포맷 설계 가이드: 필요한 데이터만 로깅하기

기본 Combined Log Format은 범용적이지만, 특정 분석 목적에 맞춘 커스텀 로그 포맷이 더 효율적일 수 있습니다. 불필요한 필드를 제거하고 필요한 데이터만 로깅하는 방법을 알아봅니다.


기본 Combined Log Format의 문제

`` 192.0.2.100 - - [10/Oct/2024:14:00:00 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0" `

  • - -: 거의 항상 하이픈 (사용 안 함)
  • Referer가 없으면 "-" (공간 낭비)
  • 응답시간, 캐시 상태, 백엔드 정보 없음

목적별 커스텀 포맷

1. 보안 분석 중심

`nginx log_format security '$remote_addr [$time_local] "$request" $status "$http_user_agent" "$request_body"'; `

  • IP, 요청, 상태 코드, User-Agent에 집중
  • Referer, 바이트 수 제거

2. 성능 분석 중심

`nginx log_format performance '$time_local $request_time $upstream_response_time "$request" $status $body_bytes_sent'; `

  • 시각, 응답시간, 백엔드 시간에 집중
  • IP, User-Agent 제거

3. 트래픽 분석 중심

`nginx log_format traffic '$remote_addr $request_method $uri $status $body_bytes_sent "$http_referer"'; `

  • IP, 메서드, 경로, 바이트에 집중
  • User-Agent 제거

4. 캐시 분석 중심

`nginx log_format cache '$time_local "$request" $status $upstream_cache_status $body_bytes_sent'; `

  • 캐시 히트/미스 상태 중심
  • IP 제거 (캐시 성능은 클라이언트 무관)

JSON 로그 포맷

파싱이 쉽고 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; } `

특정 IP 제외 (내부 헬스체크)

`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; `


Syslog 전송

중앙 로그 서버로 실시간 전송:

`nginx access_log syslog:server=10.0.0.1:514,tag=nginx combined; `


로그 포맷 변수 전체 목록

요청 정보

응답 정보

시간

클라이언트

백엔드

변수의미
------------
$request전체 요청 라인
$request_methodGET, POST 등
$request_uri전체 URI + 쿼리
$uri경로만 (쿼리 제외)
$args쿼리 문자열만
$request_bodyPOST 바디
변수의미
------------
$statusHTTP 상태 코드
$body_bytes_sent응답 바이트
$bytes_sent헤더 포함 전체 바이트
변수의미
------------
$time_local로컬 시각
$time_iso8601ISO 8601 형식
$msecUNIX 타임스탬프 (밀리초)
$request_time총 요청 처리 시간
변수의미
------------
$remote_addr클라이언트 IP
$http_user_agentUser-Agent
$http_refererReferer
$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 포맷은 자동화 분석에 유리합니다.