자동화 파이프라인9 분 읽기

감시판의 빨간불 3개가 전부 오탐이었고, 진짜 사각은 회색 칸이었습니다

봇 감시판이 지연 3건을 띄웠습니다. 셋 다 거짓이었습니다 — 기대 주기가 실제 스케줄과 달랐을 뿐입니다. 그런데 같은 화면의 '무산출' 3칸은 아무도 안 보고 있었고, 그중 하나는 60일짜리 토큰 갱신을 통째로 건너뛰고 있었습니다.

#automation-pipeline#monitoring#reality-check#first-principles#tools-setup
왼쪽은 지연으로 표시된 세 행이 전부 실제 스케줄과 맞지 않는 기대 주기 설정 때문에 생긴 오탐이라는 것, 오른쪽은 무산출로 표시돼 영구히 보이지 않던 세 행 중 하나가 토큰 갱신을 조용히 건너뛰고 있었다는 것
빨간불은 거짓이었고, 회색 칸이 진짜였습니다.

봇 34대를 산출물 기준으로 감시하는 화면이 있습니다. 상태코드는 안 봅니다 — exit 0이 거짓말한다는 걸 이미 겪었기 때문에, 각 봇이 마지막으로 무엇을 언제 만들었는지만 봅니다.

그 화면이 지연 3건을 띄우고 있었습니다. 열어보니 셋 다 거짓이었습니다.

당신 감시판의 경보 하나를 붙잡고 물어보세요 — 이게 진짜 고장입니까, 아니면 임계값이 틀린 겁니까?

빨간불 3개

첫 번째는 페이퍼 트레이딩 봇이었습니다. 1일 전 산출, 기대 주기 1일 → 지연.

plist를 봤습니다.

StartCalendarInterval:
  Weekday: 2,3,4,5,6    # 화~토
  Hour: 8

주말에 안 돕니다. 토요일 08:00이 마지막이면 일요일과 월요일 아침에는 반드시 하루 이상 공백이 생깁니다. 주말마다 빨간불이 켜지도록 설정해 둔 것이지 봇이 고장난 게 아니었습니다.

나머지 둘은 토큰 갱신 잡이었습니다. 기대 주기 3일, 3일 전 산출 → 지연. plist는 Weekday: 1, 즉 주 1회였습니다. 3일마다 확인하도록 감시해 놓고 7일마다 도는 잡이니, 나흘 내내 빨간불입니다.

셋 다 봇은 멀쩡했고 감시 설정이 틀렸습니다.

그래서 34개를 전부 대조했습니다

여기서 멈추면 다음 주에 또 다른 오탐을 봅니다. 그래서 감시판에 적힌 기대 주기와 실제 plist 스케줄을 34개 전부 1:1로 찍어봤습니다.

두 개가 더 나왔습니다. 하나는 06시부터 23시까지만 도는 잡인데 기대 주기가 4시간이었습니다. 밤 11시에서 아침 6시까지 7시간이 비니, 새벽마다 깜빡이게 되어 있었습니다. 다른 하나도 화~토 잡인데 주기가 2일이었습니다.

그리고 더 근본적인 게 보였습니다. 주기 = 최대 정상 공백입니다. 여유가 0이면 어떤 잡이든 다음 실행 직전에는 경과 비율이 1을 넘습니다. 매일 도는 잡은 매일, 주간 잡은 매주 한 번씩 잠깐 빨개집니다.

# 여유 25%: 주기가 곧 최대 정상 공백이라 다음 실행 직전은 항상 ratio≈1이 된다.
ratio = (time.time() - mtime) / (period * 1.25)

주기값 5개를 고치고 여유 25%를 넣었습니다. 34대 중 지연 0이 됐습니다.

여기서 갈립니다 — 당신이라면?

여기까지가 요청받은 일이었습니다. "지연 3건은 뭐야, 처리 안 해도 될까?" 답은 "전부 오탐, 처리 완료"입니다. 끝내도 됐습니다.

그런데 같은 화면에 다른 상태가 3칸 있었습니다. 무산출.

A. 넘어간다. 텔레그램으로만 알리는 잡이라 파일 산출이 없는 게 설계다. B. 파고든다. 감시 대상에 올려놓고 볼 수단이 없다는 게 말이 되나.

B를 골랐습니다. 그리고 거기 진짜가 있었습니다.

회색 칸이 진짜였습니다

무산출 셋 중 하나가 SNS 토큰 갱신 잡이었습니다. 매월 1일 08:00, 장기 토큰을 60일 연장합니다.

$ launchctl print gui/501/com.***.refresh | grep runs
	runs = 0
 
$ ls logs/refresh.out.log
No such file or directory

한 번도 안 돌았습니다. launchd는 프로세스를 띄우는 순간 stdout 파일을 만듭니다. 파일이 없다는 건 발화 자체가 없었다는 뜻입니다. 8월 1일 08:00에 맥이 깨어 있지 않았고, 그 세션은 그대로 사라졌습니다.

토큰 수명이 60일입니다. 다음 달 1일도 놓치면, 그때는 갱신 기회 없이 만료됩니다. 그 계정에 걸린 자동 게시가 전부 조용히 멈춥니다. 에러 없이, 알림 없이.

수동으로 돌려보니 정상 작동했습니다(약 60일 연장). 코드 문제가 아니라 한 번의 누락이 곧 만료가 되는 스케줄이 문제였습니다.

주 1회로 바꿨습니다. 갱신은 멱등이라 자주 돌아도 손해가 없고, 주 1회면 8번 연속 실패해야 위험해집니다. 월 1회는 1번 실패하면 끝입니다.

감시 대상이 되려면 흔적이 있어야 합니다

남은 무산출 하나는 매시간 텔레그램 요약을 쏘는 잡이었습니다. 파일을 안 남기니 화면에서 영원히 회색입니다. 죽어도 모릅니다.

한 줄 추가했습니다.

echo "$(date '+%Y-%m-%d %H:%M') heartbeat 발송 rc=$CODE ..." >> "$DIR/heartbeat.log"

보낸 사실 자체를 남깁니다. 이제 감시판이 그 파일의 나이를 잽니다.

자가진단 3개

  1. 감시판의 기대 주기가 실제 스케줄과 일치합니까? 주중만 도는 잡, 야간에 쉬는 잡, 격주 잡. 한 번은 1:1로 대조해 보세요. 저는 34개 중 5개가 틀렸습니다.
  2. 경보 임계에 여유가 있습니까? 주기를 그대로 임계로 쓰면 멀쩡한 잡이 매 주기 끝자락마다 깜빡입니다. 그 깜빡임이 반복되면 사람은 경보를 무시하기 시작합니다.
  3. "산출물 없음"으로 표시된 칸이 있습니까? 그건 정상이 아니라 감시 불가입니다. 흔적을 남기게 하거나, 감시판에서 빼세요. 회색으로 남겨두면 볼 수 없는 걸 보고 있다고 착각하게 됩니다.

솔직한 부분

오탐 3개를 고친 건 사실 별 가치가 없습니다. 봇은 처음부터 멀쩡했고, 제가 화면을 잘못 만들어놨던 것뿐입니다.

가치가 있었던 건 오탐을 고치다가 회색 칸을 열어본 것입니다. 빨간불은 시끄러워서 언젠가는 봤을 겁니다. 회색 칸은 조용해서, 안 열어봤으면 9월 1일에 토큰이 만료되고 나서야 알았을 겁니다. 그때는 왜 게시가 멈췄는지 찾는 데 또 반나절을 썼겠죠.

경보의 진짜 실패 모드는 안 울리는 게 아닙니다. 거짓으로 자주 울려서 사람이 화면 자체를 안 믿게 되는 것입니다. 오탐을 방치하면 그 옆의 진짜 신호까지 같이 죽습니다.

지금 당신 감시판에서 "정상"도 "실패"도 아닌 애매한 상태로 오래 앉아 있는 항목을 하나 찾아보세요. 그게 제일 오래 방치된 문제일 가능성이 높습니다.

관련 글