로그 파일이 없다는 것
감시판에 잡을 하나 새로 등록하다가 이상한 걸 봤습니다. 스토어 리스팅을 긁어 오는 launchd 잡이 적재된 이후 runs = 0이었습니다. 실패한 기록이 아니라 실행된 기록 자체가 없었습니다. 로그 파일도 만들어진 적이 없었습니다.
이 잡은 sources/app_listings.json을 갱신합니다. 이 파일은 자동으로 나가는 Threads·Facebook 글 본문의 유일한 접지 근거입니다. 글에 적히는 앱 설명, 그리고 '무료'라고 써도 되는지 가격을 검증하는 값이 모두 여기서 나옵니다.
당신의 자동화에도 이런 잡이 있지 않나요? 결과물을 다른 파이프라인이 읽기만 하고, 그 잡이 마지막으로 언제 돌았는지는 아무도 확인하지 않는 잡 말입니다.
이 잡은 에러를 낸 적이 없습니다. 돌지 않았으니 에러를 낼 기회도 없었습니다. 그리고 감시 대상 목록에 없었기 때문에, 조용한 게 정상인지 비정상인지 판단하는 주체가 아무도 없었습니다.
원인: Day 키 하나
plist의 StartCalendarInterval에 Day = 1이 들어 있었습니다. launchd에서 Day는 '매월 며칠'입니다. 그래서 이 잡은 매일 08:10에 도는 잡이 아니라, 매월 1일에만 도는 잡이었습니다.
StartCalendarInterval:
Day: 1 # 매월 1일
Hour: 8
Minute: 10문법상 틀린 곳은 없습니다. launchctl은 이 설정을 문제없이 받아들이고, 적재도 정상으로 보입니다. 설정이 '틀렸다'는 신호는 어디에서도 나오지 않습니다. 의도와 다른 주기일 뿐입니다.
적재 시점부터 아직 다음 1일이 오지 않았으니 runs가 0인 것은 launchd 입장에선 완벽하게 정상입니다.
낡은 근거가 만드는 피해
월 1회 갱신이라면, 글은 최대 30일 전의 스토어 카피를 근거로 나갑니다. 그 사이 스토어 설명을 고쳤어도 글에는 옛 문장이 인용됩니다. 더 곤란한 건 가격입니다. '무료' 여부를 검증하는 단계도 같은 파일을 읽기 때문에, 검증이 통과해도 그건 낡은 값에 대한 통과입니다.
접지(grounding)를 해 놓았다는 사실이 오히려 안심을 줍니다. 근거 파일이 있으니 글이 사실에 붙어 있다고 믿게 됩니다. 하지만 근거 파일의 신선도는 아무도 보증하지 않고 있었습니다.
당신이라면 여기서 매일로 바꾸겠습니까, 아니면 주기를 다시 정하겠습니까?
수정
Day = 1을 빼고 매주 월요일에 돌도록 바꿨습니다. 커밋 제목 그대로 '매월 1일 → 매주 월요일'입니다.
그리고 다음 월요일을 기다리지 않고 강제로 1회 실행해서 갱신을 확인했습니다. 결과는 리스팅 47/47, ASO 47/47, exit 0이었습니다. app_listings.json은 이 실행으로 실제로 내용이 바뀌었습니다.
이 잡이 드러난 계기는 감시판에 등록하는 작업 자체였습니다. 즉 이번 수정의 절반은 plist 한 줄이고, 나머지 절반은 이 잡을 감시 범위 안에 넣은 것입니다.
자가진단 체크리스트
- 다른 파이프라인이 읽는 파일마다, 그 파일을 만드는 잡의 '마지막 실행 시각'을 지금 바로 답할 수 있습니까?
- launchd
StartCalendarInterval에Day나Weekday키가 들어 있다면, 그게 의도한 주기인지 한 번씩 읽어 봤습니까? - 감시가 '실패'만 잡고 있습니까, 아니면 '한 번도 안 돈 것'과 '로그가 없는 것'도 이상으로 취급합니까?
솔직한 부분
주간으로 바꿨어도 근거는 여전히 최대 7일 낡을 수 있습니다. 그게 충분한지는 아직 판단 근거가 없습니다. 또 잡이 돌지 않던 기간에 나간 글 중 실제로 스토어와 다른 설명이나 틀린 가격 표기가 들어간 글이 있었는지는 확인하지 못했습니다. 갱신 전 파일이 얼마나 오래된 값이었는지도 정확히 모릅니다. 확실한 건, 감시판에 등록하지 않았다면 다음 달 1일까지 이 사실을 알 방법이 없었다는 것뿐입니다.