이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- Nginx access log와 error log는 Spring 장애 분석에서 각각 어떤 역할을 하는가?
- 499, 502, 504, 413을 로그만 보고 어떻게 1차 분류하는가?
- 장애 중 공유 가능한 로그 증거를 어떻게 남겨야 하는가?
개요
Nginx log는 사용자의 요청이 Spring에 도달하기 전후를 보여 주는 첫 번째 증거다.
access log는 요청별 status, 응답 시간, upstream 상태를 남긴다.
error log는 upstream connection 실패, timeout, 설정 오류, 파일 접근 오류 같은 내부 원인을 남긴다.
Spring log만 보면 Nginx에서 차단된 요청이나 client가 끊은 요청을 놓칠 수 있다.
Access Log와 Error Log
access log는 모든 요청의 결과를 행 단위로 남긴다.
장애 중에는 status code 분포, 특정 URI, request time, upstream response time을 본다.
error log는 Nginx가 요청 처리 중 만난 문제를 남긴다.
502, 504, static file 404, permission denied, certificate path 문제는 error log에 단서가 남을 수 있다.
두 로그를 같은 시간대로 봐야 한다.
Log Format 예시
log_format api_main '$remote_addr "$request" status=$status '
'bytes=$body_bytes_sent rt=$request_time '
'ustatus=$upstream_status urt=$upstream_response_time '
'host=$host reqid=$request_id ua="$http_user_agent"';
access_log /var/log/nginx/api.access.log api_main;
error_log /var/log/nginx/api.error.log warn;request_time은 Nginx가 client 요청을 처리한 전체 시간이다.
upstream_response_time은 upstream에서 응답을 받는 데 걸린 시간이다.
upstream_status가 비어 있으면 Spring까지 가지 않은 요청일 수 있다.
request_id는 Nginx와 Spring log를 묶는 데 쓸 수 있다.
Request ID 전달
Nginx가 만든 request id를 Spring으로 전달하면 로그 연결이 쉬워진다.
location / {
proxy_set_header X-Request-ID $request_id;
proxy_pass http://127.0.0.1:8080;
}이미 앞단 gateway나 client가 request id를 보낸다면 어느 값을 우선할지 정해야 한다.
중요한 것은 Nginx access log와 Spring application log에서 같은 요청을 찾을 수 있어야 한다는 점이다.
Status별 1차 분류
413은 request body가 Nginx limit을 넘었을 가능성을 먼저 본다.
Spring log에 요청이 없으면 Nginx나 앞단에서 차단된 것이다.
499는 client가 연결을 먼저 끊은 신호다.
서버가 느려서 client timeout이 난 것인지, client network 문제인지 request time과 frontend timeout을 같이 본다.
502는 upstream connection 실패나 잘못된 upstream 응답을 의심한다.
504는 upstream 응답 지연을 의심한다.
디버깅 순서
nginx -t
tail -n 200 /var/log/nginx/api.access.log
tail -n 200 /var/log/nginx/api.error.log
journalctl -u nginx --since "10 minutes ago"먼저 설정 문법과 reload 오류를 확인한다.
그 다음 access log에서 status와 URI를 좁힌다.
마지막으로 error log와 Spring log를 같은 request id 또는 시간대로 연결한다.
로그를 볼 때는 timezone을 맞춘다.
민감 정보
로그는 장애 분석 자료이지만 민감 정보 저장소가 되면 안 된다.
Authorization header, cookie, session id, 주민번호, email 원문, request body를 그대로 남기면 사고 범위가 커진다.
Query string에도 token이나 개인정보가 들어갈 수 있다.
장애 공유용 로그는 필요한 필드만 남기고 민감 값은 masking한다.
운영 체크리스트
- access log에 status, request time, upstream status, upstream response time이 있는가?
- error log 경로와 log level이 문서화되어 있는가?
- Nginx request id가 Spring log와 연결되는가?
- timezone과 log rotation 정책을 알고 있는가?
- 민감 header와 query string이 로그에 남지 않는가?
- 499, 502, 504, 413을 구분하는 runbook이 있는가?
- 장애 중 공유할 log sample 형식이 정해져 있는가?
장애 신호
- 502가 늘지만 Spring log에는 같은 시간대 요청이 없다.
- 504가 늘고
upstream_response_time이 timeout 값 근처에 몰린다. - 499가 늘고
request_time이 frontend timeout과 비슷하다. - 413이 늘고 upload endpoint에서만 발생한다.
- error log에
permission denied가 나오며 static file이 403으로 응답한다. - request id가 없어 Nginx log와 Spring log를 연결하지 못한다.
안전한 완화 조치
로그가 부족하다고 장애 중 debug log를 무작정 켜면 disk와 noise가 늘 수 있다.
필요한 location이나 짧은 시간에만 log level을 조정한다.
민감 정보가 찍힌 로그는 공유하지 말고 접근 권한과 보존 기간을 확인한다.
502와 504가 섞여 있으면 upstream 연결 문제와 처리 지연 문제를 나눠서 본다.
로그 파일이 커져 disk를 압박하면 log rotation과 수집 상태를 확인한다.
인프라 담당자와 공유할 자료
증상: /api/orders 504 증가
기간: 2026-07-01 14:00~14:10 KST
Nginx sample: status=504 rt=30.001 urt=30.000 reqid=abc123
Spring sample: reqid=abc123 DB lock wait
최근 변경: 주문 조회 query 배포
판단: Nginx timeout이 아니라 upstream 처리 지연좋은 로그 공유는 status 하나가 아니라 시간, URI, request id, Nginx 시간, Spring 원인을 함께 묶는다.
실전 팁
- access log는 요청 결과, error log는 Nginx 내부 원인을 본다.
upstream_status가 비어 있으면 Spring 도달 여부부터 확인한다.- request id는 장애 전부터 남겨야 장애 중 쓸 수 있다.
- log rotation이 없으면 장애 중 disk full이 2차 장애가 된다.
- 민감 값 masking은 분석 편의보다 우선한다.
위험 신호!
- Spring log에 없다는 이유로 요청이 없었다고 판단한다.
- 499를 모두 사용자 탓으로 돌린다.
- error log를 보지 않고 timeout만 조정한다.
- Authorization header나 cookie를 그대로 로그에 남긴다.
- 장애 중 전체 debug log를 오래 켜 둔다.
확인 질문
확인 질문
- access log와 error log의 역할 차이는 무엇인가?
- access log는 요청별 결과와 시간을 보여 주고, error log는 Nginx 내부 처리 실패와 upstream 연결 문제의 원인을 보여 준다.
upstream_status가 비어 있으면 무엇을 의심해야 하는가?
- 요청이 Spring upstream까지 전달되지 않았거나 Nginx가 정적 파일, body size, redirect 등 자체 처리로 끝냈을 가능성을 봐야 한다.
- 장애 공유용 로그에는 무엇이 포함되어야 하는가?
- 시간대, URI, status, request time, upstream status/time, request id, Spring log 연결 정보, 최근 변경 사항이 포함되어야 한다.