lifecarelog
백엔드

cron이 조용히 멈출 때: launchd 데드맨 스위치로 감지하기

잡이 돌다 실패하면 로그가 남지만 아예 안 돌면 로그조차 없어요. launchd 데드맨 스위치로 조용히 멈춘 cron 자동화를 감지하는 방법을 정리했어요.

6분 읽기

cron이 조용히 멈출 때: launchd 데드맨 스위치로 감지하기

자동화가 실패하면 알림이 오도록 해뒀는데, 어느 날 보니 잡이 일주일째 아예 안 돌고 있었던 적 없나요? 라이프케어로그 블로그 글 자동 발행 파이프라인을 운영하면서 직접 겪은 일이에요. 에러 알림 코드는 멀쩡했는데, 알림을 보낼 프로세스 자체가 죽어 있었거든요.

에러 로그가 없는 실패

백엔드 자동화의 실패는 두 갈래예요. 하나는 잡이 돌다가 실패하는 경우죠. API가 500을 주거나 DB 커넥션이 끊기면 에러 로그가 남고, 로그 기반 알림이 잡아줘요. 다른 하나는 잡이 아예 안 뜨는 경우예요. 데몬이 죽거나, 컨테이너가 재시작되면서 스케줄러가 함께 사라지거나, 맥이라면 절전 중에 잡힌 스케줄이 그냥 건너뛰어져요. 이때는 실패 로그조차 안 남아요. 로그가 없으니 로그를 보는 알림은 영원히 조용하고요.

돌다가 실패(에러 로그 있음, 알림 가능) vs 아예 안 돎(로그 없음, 기존 알림으로 감지 불가)

성공의 흔적을 남기고, 그 부재를 감시하기

데드맨 스위치 패턴은 관점을 뒤집어요. 실패를 찾는 대신 성공이 끊긴 걸 찾는 거죠.

  1. 본 작업이 성공할 때마다 last_success 파일에 타임스탬프를 기록해요.
  2. 완전히 별도의 감시자가 주기적으로 그 파일의 나이를 확인해요.
  3. 30분 넘게 갱신이 없으면 알림을 보내요.

3단계면 끝나요. 직접 만들어 보니 두 가지가 중요했어요. 기록은 진짜 성공 뒤에만 해야 해요. exit code 0이 아니라 실제로 DB에 행이 들어갔는지 확인한 다음에요. 그리고 감시자는 본 작업과 다른 실행 경로에 둬야 해요. 같은 스케줄러에 넣으면 스케줄러가 죽을 때 같이 죽으니까요.

launchd로 독립 감시자 만들기

맥에서 돌리는 자동화라면 launchd가 감시자로 알맞아요. cron과 달리 절전으로 놓친 스케줄을 깨어난 뒤 실행해 주고, plist 파일 1개와 셸 스크립트 1개면 돼요.

<key>StartInterval</key>
<integer>600</integer>

StartInterval은 초 단위라 600이면 10분마다 실행돼요. 감시 스크립트는 파일 나이만 계산하면 되고요.

AGE=$(( $(date +%s) - $(stat -f %m "$HEARTBEAT") ))
if [ "$AGE" -gt 1800 ]; then
  send_alert "자동화가 30분째 조용해요"
fi
본 작업 성공실제 결과 확인last_success 갱신launchd 감시자가 파일 나이 확인임계 초과 시 알림

타임스탬프는 임시 파일에 쓰고 mv로 옮기면 쓰다 만 파일을 읽는 문제를 피할 수 있어요. 적용해 봤더니 설정 전체에 10분 정도 걸렸고, 며칠 뒤 절전으로 잡이 밀렸을 때 첫 알림이 실제로 왔어요. 테스트해 보면 하트비트 파일을 지우고 한 주기만 기다려도 동작 확인이 돼요. 플랜엘(plan-l)처럼 외부 데이터에 기대는 서비스일수록 갱신 잡의 침묵이 곧 장애라, 이 감시자 하나가 마음을 꽤 놓이게 해줘요.

침묵도 신호예요

모니터링은 소리 나는 실패만 잡기 쉬워요. 그런데 혼자 여러 자동화를 돌리다 보면 진짜 무서운 건 조용한 멈춤이더라고요. 지금 운영 중인 cron 가운데 마지막 성공 시각을 즉시 답할 수 없는 잡이 있다면, 오늘 하트비트 파일 하나부터 남겨 보세요.

#cron#launchd#백엔드 모니터링

라이프케어로그 서비스가 궁금하신가요?

AI 기반 건강·일정·재활 관리 앱을 직접 써보세요.

서비스 살펴보기

관련 글

댓글

아직 댓글이 없어요. 첫 댓글을 남겨주세요.