서버 500 오류 발생 시 로그부터 확인해야 하는 이유
서버 다운의 순간은 언제나 당황스럽습니다. 특히 금요일 밤, 갑작스럽게 모니터링 알람이 터지고 사용자들은 '500 Internal Server Error' 화면을 만날 때의 그 막막함은 저도 수없이 경험했습니다. 그때마다 '일단 서버 재부팅' 버튼을 누르고 싶었지만, 제 경험상 그 행동은 원인 분석의 골든 타임을 스스로 날리는 행위였습니다. 가장 먼저 해야 할 일은 단 하나, 바로 '로그(Log) 확인'입니다. 지금부터 그 이유와 제가 실제로 사용했던 분석 순서를 공유해 드립니다.
1. 서버 다운, 맨붕에 빠진 당신: 왜 '로그'부터 봐야 하는가?
서버가 다운되거나 500 에러를 뱉어낼 때, 가장 위험한 행동은 '추측'입니다. 메모리 부족일까? DB 연결 문제일까? 로그는 서버가 멈추기 직전까지의 모든 행동을 기록한 유일한 목격자입니다. 로그를 먼저 봐야 하는 이유는 단순합니다. 재부팅은 임시방편일 뿐, 근본 원인을 기록한 휘발되지 않는 증거를 먼저 확보해야 다음 번 다운을 막을 수 있기 때문입니다. 재부팅을 하는 순간, 메모리나 임시 버퍼에 있던 결정적인 단서들이 사라질 수 있습니다.
2. 500 에러는 거짓말쟁이: 로그 분석의 '골든 타임'과 숨겨진 원인
사용자에게 보이는 '500 Internal Server Error'는 사실 모든 종류의 내부 오류를 포괄하는 가장 모호한 오류 코드입니다. 이것만으로는 NullPointerException인지, Connection Pool Exhausted인지, OutOfMemoryError인지를 전혀 알 수 없습니다. 서버 재부팅이나 복구가 시작되면 새로운 로그가 쌓이면서 결정적인 오류 로그가 밀려날 수 있습니다. 따라서 다운 직후 *바로* 로그 파일의 마지막 부분을 확인하는 것이 핵심적인 '골든 타임'입니다. 이 시간을 놓치면 오류의 원인을 찾는 데 며칠이 걸릴 수도 있습니다.
3. 로그 파일은 어디에 있나? Nginx/Apache/WAS별 로그 위치 확인법
당황하지 않고 로그를 확인하려면, 주요 컴포넌트별 로그 파일 위치를 미리 숙지해야 합니다. 다음은 일반적인 로그 위치입니다.
- Nginx/Apache (접근 로그/오류 로그):
/var/log/nginx/또는/var/log/httpd/ - Java WAS (Tomcat/Jetty):
$TOMCAT_HOME/logs/(catalina.out, localhost_access_log 등) - 시스템 로그 (OOM 확인):
/var/log/messages또는/var/log/syslog
팁: 로그 파일을 찾을 때는 실시간 감시 명령어인 tail -f [파일명] 대신, 오류 직후 상황을 보려면 tail -n 500 [파일명]으로 과거 기록을 먼저 확인해야 합니다.
4. 실수를 줄이는 설정: 로그 레벨을 Debug로 높여야 할 때
평소에는 성능 문제로 인해 로그 레벨을 'INFO'나 'WARN'으로 설정하는 것이 일반적입니다. 하지만 재현하기 어려운 복잡한 오류나 예상치 못한 서비스 장애가 연속적으로 발생한다면, 일시적으로 로그 레벨을 'DEBUG'로 높이는 조치가 필요합니다. 물론 디스크 I/O와 용량 문제가 발생할 수 있지만, 문제 상황에서 훨씬 더 상세한 변수 값, 메서드 호출 순서 등의 정보를 얻을 수 있어 근본 원인 파악 시간을 획기적으로 줄여줍니다. 분석이 끝나면 반드시 원래 레벨로 되돌려야 합니다.
5. 서버를 되살린 3단계 분석 순서: 꼬리물기 기법
제가 금요일 밤 서버 다운 상황에서 실제로 사용했던 3단계 분석 순서(꼬리물기 기법)입니다. 이 순서는 난이도가 낮은 시스템 상태 확인부터 시작하여, 점점 애플리케이션의 핵심부로 파고드는 방식입니다.
- 1단계: 시스템 레벨 확인 (Health Check):
top,free -m명령어로 CPU, Memory, Disk I/O 사용량 급증 여부를 확인합니다. 메모리 문제(OOM)가 시스템 로그에 남았는지도 함께 확인합니다. - 2단계: WAS 및 애플리케이션 로그 확인 (Initial Search): 가장 최근 오류 발생 시점의 애플리케이션 로그 파일(예: catalina.out)의 맨 끝을 확인하여
Exception또는Error키워드를 검색합니다. - 3단계: Traceback 추적 (Root Cause): 발견된 Exception의 최초 라인(Caused by...)을 찾아내고, 그와 연결된 사용자 Request ID 또는 쓰레드 ID를 역추적하여 문제 발생 당시 어떤 API가 어떤 데이터를 처리했는지를 파악합니다. 이것이 꼬리물기 기법의 핵심입니다.
6. 2주 후, 시스템 안정화를 위해 내가 적용한 '3가지 변화'
서버 다운 악몽을 겪은 후, 저는 향후 시스템 안정성을 확보하기 위해 2주에 걸쳐 인프라에 세 가지 핵심 변화를 적용했습니다. 단순히 재발 방지뿐 아니라, 향후 장애 발생 시 대응 속도를 높이는 것이 목표였습니다.
- 중앙 집중식 로깅 시스템 도입: 다운된 서버에 직접 접속하지 않고도 모든 로그를 실시간으로 모니터링할 수 있도록 ELK 스택(Elasticsearch, Logstash, Kibana)을 구축했습니다. 이는 분석 시간을 획기적으로 줄여주었습니다.
- 로그 상세도 조정 및 보존 기간 연장: 프로덕션 환경의 ERROR 로그 레벨에서 중요한 변수나 HTTP 헤더 일부를 마스킹하여 기록하고, 로그 보존 기간을 기존 3일에서 최소 7일로 연장하여 과거 데이터 기반 분석을 가능하게 했습니다.
- 특정 로그 패턴 기반 자동 알림 설정:
OutOfMemoryError나Connection refused와 같은 치명적인 키워드가 로그에 포착될 경우, 단순히 서버 다운 알림 외에 로그 패턴 기반으로 슬랙(Slack) 알림이 즉시 오도록 설정하여 장애 발생에 대한 사전 대응력을 높였습니다.