배포와 인프라9 분 읽기

주 3회 도는 잡을 매일 기준으로 감시했습니다 — 경보의 절반이 가짜였습니다

감시판은 잡마다 '기대 주기'를 갖고 산출물 신선도로 판정합니다. 그 주기가 실제 스케줄과 다르면, 안 도는 날마다 지연 경보가 켜집니다.

#monitoring#automation#gotchas#metrics
왼쪽은 화·목·토에만 실행되는 잡의 실제 스케줄, 오른쪽은 매일 기준으로 판정해 실행이 없는 날마다 지연으로 표시되는 감시판
같은 잡, 같은 로그. 왼쪽은 실제 스케줄, 오른쪽은 감시판이 가정한 스케줄입니다.

봇 40여 대를 한 화면에서 봅니다. 종료 코드는 믿지 않기로 오래전에 정했습니다. 대신 산출물의 신선도로 판정합니다. 잡마다 "기대 주기"를 적어두고, 마지막 산출물이 그 주기를 넘겼으면 지연으로 칩니다.

질문 하나 드리겠습니다. 당신의 감시판은 잡의 스케줄을 어디서 알고 있습니까? 스케줄러에서 읽어옵니까, 아니면 누가 손으로 적어둔 숫자입니까?

매주 이틀은 빨간불이었습니다

옵션 미결제약정을 모으는 수집기 하나가 있습니다. 감시판에서 이 잡은 자주 지연으로 떴습니다. 로그를 열면 늘 정상이었습니다. 마지막 줄은 [end] ok, 산출물도 있고 데이터도 맞습니다. 그런데 다음 날 다시 보면 또 지연입니다.

감시 설정을 봤습니다.

("com.ootssu.sqz.options", "옵션 OI·맥스페인", D,
 ".../logs/options.err.log", "21:45 · 0건이면 실패로 종료", ...)

D는 하루입니다. 즉 "이 잡은 매일 21:45에 돌고, 산출물이 하루보다 낡으면 지연"이라는 뜻입니다. 그리고 실제 스케줄 파일을 열어봤습니다.

Weekday 3  21:45   (화)
Weekday 5  21:45   (목)
Weekday 7  21:45   (토)

주 3회입니다. 화·목·토. 그러니까 수·금·일·월에는 정상적으로 산출물이 하루보다 낡습니다. 감시판은 그 나흘 중 상당 부분을 지연으로 칠했고, 나는 그걸 몇 주 동안 "또 그거"로 넘겼습니다.

가짜 경보의 비용은 경보 하나가 아닙니다. 같은 화면의 진짜 경보를 읽지 않게 되는 습관입니다. 감시판을 만든 이유가 그 습관을 없애는 것이었는데, 잘못된 주기 하나가 그걸 되돌려놨습니다.

고침은 한 줄이었습니다. 기대 주기를 실제 스케줄에서 계산한 최대 공백(토 → 화, 3일)으로 바꿨습니다.

# 이것만 주 3회(화·목·토 21:45)다 — plist 실측. D로 두면 안 도는 날마다
# 지연으로 깜빡였다. 최대 공백은 토→화 3일이라 주기도 3일이다.
("com.ootssu.sqz.options", "옵션 OI·맥스페인", 3 * D, ...)

같은 화면의 다른 거짓말: "7일 순증"

같은 감시판에 팔로워 성장 카드가 있습니다. "일간 / 7일 순증"을 보여줍니다. 며칠째 7일 쪽이 였습니다.

계산은 이랬습니다.

baseline = account.get((asof - timedelta(days=7)).isoformat())
return followers - baseline if baseline is not None else None

정확히 7일 전 날짜 키가 있어야 값이 나옵니다. 야간 수집이 하루라도 실패하면 그 날짜가 비고, 7일 뒤 카드가 조용히 가 됩니다. 실제 스냅샷은 8일 전에 있는데도 말입니다.

여기서 갈림길이 있었습니다. 당신이라면 어떻게 하겠습니까?

  1. 가장 가까운 스냅샷을 찾아 "7일 순증"으로 표시한다.
  2. 가장 가까운 스냅샷을 찾되, 실제 간격을 라벨에 쓴다.

1번이 편합니다. 화면도 안 비고, 아무도 불평하지 않습니다. 하지만 그건 8일 차이를 7일이라고 부르는 겁니다. 성장률을 보려고 만든 카드가 분모를 속이면 그 카드는 자산이 아니라 부채입니다.

2번으로 갔습니다. 6~8일 범위에서 7일에 가장 가까운 스냅샷을 골라 쓰고, 카드 제목 자체를 바꿉니다.

최근 8일 순증        +56
2026-09-02 → 2026-09-10 · 7일 전 자료 누락으로 실제 비교 기간 표시

같은 배치에서 라는 표기도 없앴습니다. 는 "0인지 못 읽은 건지"를 구분하지 않습니다. 이제 수집 전이면 "수집 대기", 비교 기준이 없으면 "비교 자료 부족"으로 각각 다르게 나옵니다. 0과 미측정을 같은 칸에 쓰면 안 되는 이유는 예전에 한 번 값을 치르고 배웠습니다.

두 버그는 사실 한 버그였습니다

주기 오탐과 7일 순증은 코드상 남남입니다. 그런데 원인은 같습니다.

감시판이 자기 가정을 화면에 쓰지 않았습니다.

  • 첫 번째는 "이 잡은 매일 돈다"는 가정을 숨겼습니다. 그래서 정상인 공백이 지연으로 보였습니다.
  • 두 번째는 "이 값은 정확히 7일 간격이다"는 가정을 숨겼습니다. 그래서 없는 기준을 못 만들면 그냥 침묵했습니다.

감시판의 숫자는 언제나 "무엇과 비교했는가"를 데리고 다녀야 합니다. 비교 대상이 화면에 없으면, 보는 사람은 자기가 기억하는 스케줄로 채워 넣습니다. 그리고 그 기억은 대체로 틀립니다.

자가진단 3개

  1. 기대 주기가 스케줄러 설정과 일치하는지 대조했는가. 손으로 적은 숫자는 스케줄이 바뀌는 순간부터 조용히 틀립니다. 나는 plist를 열어보기 전까지 주 3회인 줄 몰랐습니다.
  2. "N일 순증" 라벨의 N이 실측인가 가정인가. 스냅샷 하나가 비면 N은 즉시 거짓말이 됩니다. 라벨에 실제 구간을 쓰면 거짓말이 불가능해집니다.
  3. 빈 값 표기가 0과 미측정을 구분하는가. , 0, null이 한 칸에서 같은 모양이면, 판정은 이미 오염됐습니다.

솔직한 부분

이 두 고침으로 새로 잡은 장애는 없습니다. 성장률이 좋아진 것도 아닙니다. 얻은 건 하나입니다. 이제 이 화면의 빨간불은 전부 진짜입니다. 그게 감시판의 유일한 상품입니다 — 신뢰도. 가짜 경보 하나가 섞이면 나머지 39개의 값도 같이 떨어집니다.

지금 감시판을 열어 잡 하나를 고르세요. 그 잡의 기대 주기를 어디서 가져왔는지 답할 수 있습니까? 답이 "예전에 내가 적었다"라면, 스케줄러 설정을 지금 열어 대조해보세요.

관련 글