헬스체크 cron
infra/healthcheck.sh는 quant-ai 스택의 end-to-end 헬스 프로브입니다. 매일
1회 cron으로 실행되어 5개 항목을 검사하고 결과를 Telegram 일일 리포트로
보냅니다. 한 항목이라도 FAIL이면 메시지 prefix가 ALERT로 바뀌고 종료
코드가 비제로가 됩니다.
점검 항목
| # | 항목 | 검증 방법 |
|---|---|---|
| 1 | 컨테이너 모두 running | docker compose ps --services --filter status=running 와 기대 6개 비교 |
| 2 | Postgres 응답 | pg_isready |
| 3 | Redis 응답 | redis-cli ping → PONG |
| 4 | API /health 200 | curl --max-time 10 |
| 5 | Alembic at head | alembic current 출력에 (head) 포함 |
기대 컨테이너 6개:
timescaledb redis api web analysis-worker position-reconciler
사전 요구 사항
- VM에
cron서비스 동작 중 ~/quantai/.env에TELEGRAM_TOKEN/TELEGRAM_CHAT_ID설정 (옵션 — 비워도 종료코드는 정상 동작, 알림만 스킵)azureuser가docker compose실행 가능 (sudo없이 또는 NOPASSWD)
1. cron 등록
VM에서:
sudo tee /etc/cron.d/quantai-health <<'EOF'
# Daily health check at 09:00 UTC, posts to Telegram + writes log.
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 9 * * * azureuser /home/azureuser/quantai/infra/healthcheck.sh >> /var/log/quantai-health.log 2>&1
EOF
sudo chmod 644 /etc/cron.d/quantai-health
검증:
sudo crontab -u azureuser -l # 사용자 crontab은 비어 있어도 OK
ls -l /etc/cron.d/quantai-health # 644 권한 확인
sudo systemctl status cron # active (running)
2. 즉시 실행 (검증)
# VM에서 ad-hoc 실행
bash ~/quantai/infra/healthcheck.sh
# 출력 예시
quant-ai health @ vm-prod 2026-04-26T09:00:00Z
[OK] service timescaledb running
[OK] service redis running
[OK] service api running
[OK] service web running
[OK] service analysis-worker running
[OK] service position-reconciler running
[OK] postgres pg_isready
[OK] redis ping=PONG
[OK] api /health 200
[OK] alembic at head
종료 코드:
0— 모든 항목 OK1— 한 항목 이상 FAIL (Telegram에 ALERT prefix로 발송)
3. Telegram 메시지 포맷
성공:
quant-ai health @ vm-prod 2026-04-26T09:00:00Z
[OK] service timescaledb running
... (10줄)
실패:
ALERT quant-ai health @ vm-prod 2026-04-26T09:00:00Z
[OK] service timescaledb running
[FAIL] api /health returned 500
...
4. 환경변수
| 변수 | 기본값 | 설명 |
|---|---|---|
COMPOSE_FILE | docker-compose.prod.yml | VM 외부에서 테스트 시 docker-compose.yml로 |
HEALTH_URL | http://localhost:8000/health | reverse proxy 뒤에 있다면 변경 |
PROJECT_DIR | $HOME/quantai | repo 루트가 다른 경우 |
TELEGRAM_TOKEN | (옵션) | 비우면 알림 스킵 |
TELEGRAM_CHAT_ID | (옵션) | 위와 동일 |
5. 다른 시간대로 변경
운영 시간대에 맞춰 자유롭게 조정합니다.
# KST 09:00 = UTC 00:00
0 0 * * * azureuser /home/azureuser/quantai/infra/healthcheck.sh >> /var/log/quantai-health.log 2>&1
# 매 시간 (모니터링 강화 기간 한정)
0 * * * * azureuser /home/azureuser/quantai/infra/healthcheck.sh >> /var/log/quantai-health.log 2>&1
매 시간 모드에서는 OK 메시지가 시끄러우므로, 스크립트를 2>/dev/null 로
조용히 만들고 FAIL일 때만 Telegram 발송하도록 별도 cron을 두는 것을
권장합니다. 패치는 운영 환경 합의 후 PR.
6. 폴백 / 안전 동작
Telegram 실패는 무시
스크립트는 Telegram 호출에 --max-time 10 + || true를 적용합니다.
네트워크 / 봇 다운 어떤 상황에서도 종료 코드는 헬스 결과만 반영합니다 —
거래 흐름은 영향 없음.
또한 set -uo pipefail 만 설정되고 -e 는 의도적으로 빠져 있어, 한
항목 실패가 다음 점검을 차단하지 않습니다 (모든 항목을 끝까지 검사).
7. 트러블슈팅
| 증상 | 원인 / 조치 |
|---|---|
| cron이 실행되지 않음 | sudo systemctl status cron 확인. `/var/log/syslog |
| 컨테이너 점검만 FAIL | sudo 권한 부재. /etc/sudoers.d/azureuser-docker에 NOPASSWD 추가 |
pg_isready FAIL이지만 web은 동작 | DB_USER / DB_NAME 미스매치 (env 변수가 cron 환경에 전달되지 않음). cron 라인에 set -a; . ~/quantai/.env; set +a; 래핑 |
alembic NOT at head | docker compose exec api alembic upgrade head 수동 실행 |
메시지가 안 옴인데 ALERT 출력 | Telegram 변수 비어 있음. .env 갱신 후 chmod 600 .env, cron 다음 사이클 대기 |