이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- Linux 서버 장애에서 로그, 디스크, CPU, memory를 어떤 순서로 확인하는가?
- disk full, OOM, CPU saturation은 Spring 서비스에 어떻게 나타나는가?
- 로그 삭제나 임시 파일 정리를 운영 중 안전하게 하려면 무엇을 확인해야 하는가?
개요
장애 중 가장 먼저 해야 할 일은 상태를 바꾸는 명령이 아니라 읽는 명령이다.
Linux 서버에서는 로그, 디스크, CPU, memory, network socket 상태가 Spring 서비스 장애의 직접 증거가 된다.
백엔드 개발자는 서버 자원 지표를 애플리케이션 오류와 연결해 설명할 수 있어야 한다.
로그 확인
systemd로 관리되는 서비스는 journal에서 로그를 본다.
sudo journalctl -u order-api --since "30 minutes ago" --no-pager
sudo journalctl -u order-api -n 200 --no-pager파일 로그를 쓰는 경우에는 경로와 rotation 정책을 확인한다.
tail -n 200 /var/log/order-api/application.log
ls -lh /var/log/order-api로그 확인에서 중요한 것은 양보다 시간대다.
장애 시작 시각, 배포 시각, alert 발생 시각을 기준으로 로그를 좁힌다.
로그에는 endpoint, status, elapsed time, exception class, trace id가 있으면 좋다.
디스크 확인
디스크가 가득 차면 Spring 애플리케이션은 로그를 쓰지 못하고, 임시 파일 생성에 실패하고, DB나 message broker가 같은 서버에 있다면 더 큰 장애가 난다.
df -h
df -i
sudo du -xh /var/log | sort -h | tail
sudo journalctl --disk-usagedf -h는 용량을 본다.
df -i는 inode 고갈을 본다.
작은 파일이 너무 많으면 용량은 남아도 inode가 고갈될 수 있다.
du는 어떤 디렉터리가 실제로 공간을 쓰는지 찾는다.
CPU와 Memory 확인
CPU와 memory는 사용자 API 지연과 직접 연결된다.
top
ps -eo pid,user,%cpu,%mem,comm,args --sort=-%cpu | head
free -m
vmstat 1 5CPU가 높으면 busy loop, 과도한 GC, 대량 요청, 압축/암호화 작업, 로그 폭주를 의심한다.
memory가 부족하면 OOM killer가 프로세스를 종료할 수 있다.
dmesg -T | grep -i 'killed process'Spring이 갑자기 죽었는데 애플리케이션 로그가 비어 있으면 OOM kill이나 host-level 종료를 확인해야 한다.
Port와 Socket 상태
자원 문제는 socket 상태에서도 보일 수 있다.
ss -s
ss -ltnp
ss -tan state time-wait | wc -lconnection이 과도하게 쌓이면 application thread, DB pool, upstream timeout과 함께 봐야 한다.
서버 resource만 보고 애플리케이션 병목을 단정하면 안 된다.
로그와 Metric 연결
로그는 사건을 설명하고 metric은 규모와 추세를 설명한다.
예를 들어 14:05에 latency p95가 상승했다면 같은 시간대에 다음을 묶는다.
- Spring error log
- Nginx access/error log
- CPU 사용률
- memory와 swap
- disk usage
- Hikari pool pending
- GC log 또는 JVM metric
이 묶음이 있어야 “서버가 느렸다”가 아니라 “disk full로 로그 쓰기 실패와 5xx가 함께 증가했다”처럼 설명할 수 있다.
운영 체크리스트
- 장애 시간대 기준 로그 조회 명령을 알고 있는가?
- journal과 파일 로그 중 실제 운영 로그 위치를 아는가?
- log rotation 정책이 있는가?
df -h와df -i를 모두 확인하는가?- OOM kill 확인 방법이 문서에 있는가?
- CPU/memory 상위 프로세스 확인 명령이 있는가?
- 로그와 metric을 같은 시간대로 묶어 기록하는가?
장애 신호
No space left on device가 로그나 systemd journal에 보인다.df -h는 여유가 있는데df -i가 100%다.- Spring 프로세스가 갑자기 사라졌고
dmesg에 killed process가 있다. - CPU 100%와 p99 latency 상승이 같은 시간대에 나타난다.
- 로그 파일이 수십 GB로 커져 디스크를 압박한다.
- 로그가 너무 많이 출력되어 실제 오류를 찾기 어렵다.
- journal 용량이 커져 root filesystem을 채운다.
안전한 완화 조치
디스크가 찼다고 바로 로그 파일을 삭제하지 않는다.
실행 중인 프로세스가 잡고 있는 파일을 삭제하면 공간이 바로 반환되지 않을 수 있다.
sudo lsof +L1먼저 큰 파일과 디렉터리를 확인하고, rotation 또는 truncate가 안전한지 본다.
sudo truncate -s 0 /var/log/order-api/debug.logtruncate도 대상 파일을 잘못 잡으면 증거를 잃는다.
장애 분석에 필요한 로그는 압축하거나 별도 저장 후 정리한다.
CPU나 memory 문제는 무작정 restart하기 전에 상위 프로세스와 최근 배포, batch, traffic 증가를 확인한다.
인프라 담당자와 공유할 자료
증상: order-api 5xx 증가와 로그 쓰기 실패
시간대: 11:40~11:55
df -h: / 100%
du: /var/log/order-api/debug.log 38G
journal: No space left on device
최근 변경: debug logging 배포
완화: 신규 배포 중지, debug log 보존 후 truncate 검토
요청: logrotate 정책과 root filesystem 확장 가능성 확인자원 장애는 숫자와 경로를 함께 공유해야 한다.
실전 팁
- 장애 중 첫 명령은 읽기 명령으로 시작한다.
- 로그 확인은
--since로 시간 범위를 좁힌다. - disk는 용량과 inode를 모두 본다.
- OOM은 애플리케이션 로그가 아니라 kernel log에 남을 수 있다.
- 정리 작업 전에는 증거 보존과 프로세스가 잡고 있는 파일을 확인한다.
위험 신호!
- 디스크가 찼다고
/var/log아래 파일을 무작정 삭제한다. df -h만 보고 inode 고갈을 놓친다.- OOM kill을 애플리케이션 예외로만 찾는다.
- CPU가 높다는 이유만으로 바로 서버를 재시작한다.
- 장애 시간대 없이 전체 로그를 훑는다.
- 로그 레벨을 DEBUG로 올린 뒤 끄는 절차가 없다.
확인 질문
확인 질문
- disk full 상황에서
rm만으로 충분하지 않을 수 있는 이유는 무엇인가?
- 실행 중인 프로세스가 삭제된 파일을 계속 잡고 있으면 공간이 반환되지 않을 수 있고, 필요한 장애 증거를 잃을 수 있기 때문이다.
- Spring 프로세스가 갑자기 죽었는데 애플리케이션 로그가 없으면 무엇을 확인해야 하는가?
- OOM killer나 host-level 종료를 확인하기 위해
dmesg, journal, system resource 지표를 봐야 한다.- 로그와 metric을 같은 시간대로 묶어야 하는 이유는 무엇인가?
- 오류 사건과 자원 포화, 배포, traffic 증가를 연결해야 원인 후보를 좁힐 수 있기 때문이다.