웹 개발
헬스 체크 로그만 봐서는 원인을 찾기 어려울 때
헬스 체크 실패 로그를 봤을 때 어디서부터 확인해야 하는지 정리했다.
서버의 헬스 체크가 실패하면 대시보드에 빨간색으로 표시된다. 로그를 봐도 "health check failed"라는 메시지만 있고, 구체적인 원인이 안 보이는 경우가 많다.
헬스 체크가 뭘 확인하는지부터 이해
헬스 체크는 보통 다음을 본다:
- 앱 프로세스가 실행 중인가
- 앱이 지정된 포트에서 응답하는가
- 데이터베이스에 연결할 수 있는가
- 필수 외부 서비스(Redis 등)에 연결할 수 있는가
실제 설정을 확인한다:
# Docker를 쓴다면
cat docker-compose.yml | grep -A 5 healthcheck
# 또는 Kubernetes라면
kubectl get pod app-pod -o yaml | grep -A 10 livenessProbe
포트가 열려있는지부터 확인
# 서버에서 직접 앱 포트에 접근해본다
curl -v http://localhost:3000/health
응답이 없거나 timeout이 나면 앱이 포트에서 응답하지 않는 것이다. 확인할 것:
# 포트가 열려있는가
sudo ss -lntp | grep 3000
# 앱 프로세스가 실행 중인가
ps aux | grep app | grep -v grep
# 앱 로그에는 에러가 없는가
tail -f /var/log/app/app.log
데이터베이스 연결 확인
헬스 체크가 데이터베이스 상태도 확인한다면:
# 데이터베이스 서버에 접근할 수 있는가
curl -v http://localhost:5432 2>&1 | head -5
# 또는 더 정확한 확인
psql -h localhost -U dbuser -c "SELECT 1;"
만약 데이터베이스에 접근 못한다면 환경 변수를 확인한다:
# 앱이 보는 데이터베이스 주소
echo $DATABASE_URL
# Docker 컨테이너라면 실제로 뭘 봤는지 확인
docker exec app-container env | grep DATABASE
container 안에서 localhost는 호스트가 아니라 컨테이너 자신을 가리킨다. 같은 네트워크의 다른 컨테이너라면 서비스 이름을 써야 한다.
최근 로그에서 패턴 찾기
# 마지막 시간 동안의 로그를 본다
sudo journalctl -u app-service --since "1 hour ago" | tail -100
# 에러만 필터링
sudo journalctl -u app-service --since "1 hour ago" | grep -i error
헬스 체크 실패 직전에 다른 에러가 있는지 본다. 예를 들어:
- 메모리 부족으로 프로세스가 죽은 경우
- 데이터베이스 연결이 끊긴 경우
- CPU 사용률이 100%에 가까워진 경우
정상 상태와 비교
정상일 때 헬스 체크는 얼마나 자주 실행되는지 본다:
# 헬스 체크 호출 로그를 필터링
grep "GET /health" /var/log/app/access.log | tail -20
정상이면 10~30초마다 호출된다. 만약 갑자기 호출이 없거나 실패만 반복된다면, 앱 자체의 상태가 안 좋은 것이다.
재시작 전 마지막 확인
- 포트가 응답하는가
- 데이터베이스에 연결되는가
- 앱 프로세스가 정상인가 (메모리 누수, CPU 과사용 등)
이 셋을 모두 확인한 후에 앱을 재시작한다. 그러면 다음에 같은 증상이 나올 때 원인을 훨씬 빠르게 좁힐 수 있다.