← 전체 글로 돌아가기

웹 개발

헬스 체크 로그만 봐서는 원인을 찾기 어려울 때

헬스 체크 실패 로그를 봤을 때 어디서부터 확인해야 하는지 정리했다.

서버의 헬스 체크가 실패하면 대시보드에 빨간색으로 표시된다. 로그를 봐도 "health check failed"라는 메시지만 있고, 구체적인 원인이 안 보이는 경우가 많다.

헬스 체크가 뭘 확인하는지부터 이해

헬스 체크는 보통 다음을 본다:

  1. 앱 프로세스가 실행 중인가
  2. 앱이 지정된 포트에서 응답하는가
  3. 데이터베이스에 연결할 수 있는가
  4. 필수 외부 서비스(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초마다 호출된다. 만약 갑자기 호출이 없거나 실패만 반복된다면, 앱 자체의 상태가 안 좋은 것이다.

재시작 전 마지막 확인

  1. 포트가 응답하는가
  2. 데이터베이스에 연결되는가
  3. 앱 프로세스가 정상인가 (메모리 누수, CPU 과사용 등)

이 셋을 모두 확인한 후에 앱을 재시작한다. 그러면 다음에 같은 증상이 나올 때 원인을 훨씬 빠르게 좁힐 수 있다.