크론 에러 대응
증상
- 크론 작업이 예정 시간에 실행되지 않음
cron_error_alerted플래그가 설정되어 텔레그램 알림 수신- 특정 작업이 연속 실패하여 자동 비활성화됨
- jobs.json 파싱 에러 (잘못된 JSON)
원인
- jobs.json 구문 오류 — 수동 편집 시 JSON 깨짐
- 스크립트 경로 변경 — 파이프라인 스크립트 이동/삭제 후 미갱신
- 의존 서비스 장애 — DB, 네트워크, LLM 등 외부 의존 불가
- 연속 실패 임계치 초과 — 기본 정책에 의해 작업 자동 비활성화
해결 단계
1. 크론 설정 확인 및 검증
# jobs.json 유효성 검사
python3 -m json.tool ~/.openclaw/cron/jobs.json > /dev/null && echo "JSON OK" || echo "JSON INVALID"
# 전체 작업 수 및 활성 작업 확인
python3 -c "
import json
with open('$HOME/.openclaw/cron/jobs.json') as f:
jobs = json.load(f)
total = len(jobs)
active = sum(1 for j in jobs if j.get('enabled', True))
print(f'Total: {total}, Active: {active}, Disabled: {total - active}')
"
2. 실패한 작업 로그 확인
# 크론 실패 분석
python3 ~/.openclaw/workspace/scripts/cron_failure_analyzer.py
# 최근 크론 로그
ls -lt ~/.openclaw/workspace/scripts/logs/cron_*.log 2>/dev/null | head -10
3. jobs.json 수정 (atomic read-modify-write)
주의: 직접 에디터로 jobs.json을 열어 수정하지 마세요. 동시 접근 시 데이터 손실 위험.
# 1) 백업
cp ~/.openclaw/cron/jobs.json ~/.openclaw/cron/jobs.json.bak.$(date +%s)
# 2) atomic 수정 (예: 특정 작업 재활성화)
python3 -c "
import json, tempfile, os
JOBS_PATH = os.path.expanduser('~/.openclaw/cron/jobs.json')
with open(JOBS_PATH) as f:
jobs = json.load(f)
# 예: 'blog_monitor' 작업 재활성화
for j in jobs:
if j.get('id') == 'blog_monitor':
j['enabled'] = True
j.pop('cron_error_alerted', None)
j['consecutive_failures'] = 0
print(f'Re-enabled: {j[\"id\"]}')
# atomic write
tmp_fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(JOBS_PATH))
with os.fdopen(tmp_fd, 'w') as tmp:
json.dump(jobs, tmp, indent=2, ensure_ascii=False)
os.replace(tmp_path, JOBS_PATH)
print('jobs.json updated atomically')
"
4. cron_error_alerted 플래그 초기화
python3 -c "
import json, tempfile, os
JOBS_PATH = os.path.expanduser('~/.openclaw/cron/jobs.json')
with open(JOBS_PATH) as f:
jobs = json.load(f)
cleared = 0
for j in jobs:
if j.get('cron_error_alerted'):
j['cron_error_alerted'] = False
j['consecutive_failures'] = 0
cleared += 1
tmp_fd, tmp_path = tempfile.mkstemp(dir=os.path.dirname(JOBS_PATH))
with os.fdopen(tmp_fd, 'w') as tmp:
json.dump(jobs, tmp, indent=2, ensure_ascii=False)
os.replace(tmp_path, JOBS_PATH)
print(f'Cleared error alerts for {cleared} jobs')
"
5. 연속 실패로 비활성화된 작업 복구
# 비활성화된 작업 목록 확인
python3 -c "
import json
with open('$HOME/.openclaw/cron/jobs.json') as f:
jobs = json.load(f)
for j in jobs:
if not j.get('enabled', True):
print(f' DISABLED: {j.get(\"id\")} (failures: {j.get(\"consecutive_failures\", 0)})')
"
비활성화된 작업을 복구하려면 3단계의 수정 스크립트에서 해당 작업 ID를 지정하세요.
확인 방법
# JSON 유효성 재검증
python3 -m json.tool ~/.openclaw/cron/jobs.json > /dev/null && echo "OK"
# 활성 작업 수 확인
python3 -c "
import json
with open('$HOME/.openclaw/cron/jobs.json') as f:
jobs = json.load(f)
active = [j['id'] for j in jobs if j.get('enabled', True)]
print(f'Active jobs: {len(active)}')
"
# 크론 스모크 테스트
bash ~/.openclaw/workspace/scripts/cron_smoke_test.sh
# 헬스체크
python3 ~/.openclaw/workspace/scripts/health_check.py