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

제 감시판은 앱 패키지 이름을 추측하고 있었습니다

스토어에 공개된 앱은 25개인데 감시판은 22개만 보고 있었습니다. 빠진 다섯 개의 공통점은 버그가 아니라 작명이었습니다 — 제가 정한 관례를 안 지킨 앱들이었고, 목록에도 패턴에도 걸리지 않아 조용히 밖에 서 있었습니다.

#monitoring#automation-pipeline#reality-check#gotchas#verification
왼쪽: 감시 대상을 손목록과 이름 규칙으로 만들면 관례를 안 지킨 패키지 다섯 개가 후보에조차 없다. 오른쪽: 같은 날 아무도 안 건드렸는데 맞아 있던 배지는 매 렌더마다 스토어를 실제로 눌러서 판정한다
목록은 빠진 걸 말해주지 않습니다. 추측한 이름도 마찬가지입니다.

질문부터 드리겠습니다. 당신의 감시 봇은 감시할 대상을 어떻게 정합니까? 코드에 적어둔 목록입니까, 이름 규칙으로 만들어낸 후보입니까, 아니면 매번 원천에 물어봅니까?

저는 이 질문에 이미 한 번 데였습니다. 8월에 심사 감시 봇이 앱 44개 중 21개만 보고 있었다는 글을 썼습니다. 손으로 적은 21줄이 계정의 절반에서 멈춰 있던 사건이었고, 그건 원천 조회로 고쳤습니다.

그리고 어제, 다른 감시판에서 같은 자리를 또 밟았습니다. 이번에는 손목록 문제가 아니었습니다. 손목록은 이미 반쯤 고쳐놓은 상태였고, 틀린 건 이름 규칙 쪽이었습니다.

12개인 줄 알았는데 25개였습니다

안드로이드 릴리스 배선을 한 게 9월 4일입니다. 그때 스토어에 공개된 앱이 12개였고, 웹 쪽 노출 면들을 거기에 맞춰뒀습니다. 어제 무심코 다시 세어봤는데 25개였습니다. 그 사이 리뷰를 통과한 앱들이 웹에는 한 줄도 안 들어와 있었던 겁니다.

숫자를 확정하려고 46개 앱 슬러그를 전부 눌러봤습니다. 판정은 콘솔 트랙 상태가 아니라 공개 리스팅이 200을 주는가로 했습니다. 트랙이 completed여도 스토어에 안 뜨는 경우가 있고, 그 상태에서 링크를 걸면 죽은 링크가 되기 때문입니다.

그런데 전수 조회를 하려니 문제가 하나 있었습니다. 패키지 이름을 알아야 URL을 만드는데, 제 46개 앱은 패키지 이름이 두 갈래였습니다.

com.<brand>.<slug>     # 초기 앱들
com.<slug>.android     # 나중에 만든 앱들

그래서 슬러그마다 두 패턴을 다 눌러봤습니다. 이게 나중에 중요해집니다.

감시판이 더 큰 문제였습니다

웹 숫자를 맞추는 건 그냥 노동입니다. 진짜 문제는 왜 이걸 제가 손으로 세고 있는가였습니다. Play 상태를 감시하는 잡이 매일 아침 돌고 있었거든요. 그게 돌고 있는데 왜 12개에서 멈춰 있었을까요.

코드를 열었습니다.

CANDIDATES = [f"com.{BRAND}.{s}" for s in SLUGS] + [...손으로 적은 예외들...]

후보를 이름 규칙으로 생성하고, 규칙에서 새는 것들만 손으로 몇 개 적어두는 구조였습니다. 9월 4일에 앱 하나가 안 잡히길래 그 손목록에 한 줄 추가했던 기억이 났습니다. 한 줄 넣고 잘 돌아가는 걸 확인하고 닫았습니다.

그때 고친 건 그 앱 하나였습니다. 규칙은 안 고쳤습니다.

어제 전수 조회 결과와 감시 후보를 맞춰보니 다섯 개가 후보에조차 없었습니다.

com.biasly.android      스토어 200
com.bloatless.android   스토어 200
com.innra.android       스토어 200
com.moodbite.android    스토어 200
com.<brand>.stelo       스토어 200   (규칙엔 맞는데 손목록에서 누락)

앞의 넷은 com.<slug>.android 갈래라 com.<brand>.<slug> 규칙으로는 절대 안 나옵니다. 마지막 하나는 규칙에는 맞는데 슬러그 목록 쪽에서 빠져 있었습니다. 구멍이 두 종류인데 증상은 하나였습니다 — 아무 말이 없는 것.

조용하다는 게 핵심입니다

이 감시 잡은 매일 정상으로 찍혔습니다. exit 0이고, "변경 없음"도 매번 사실이었습니다. 22개를 보고 22개에 변화가 없다고 말한 거니까요. 거짓말을 한 적이 없습니다.

목록이나 패턴으로 감시 대상을 정하면 누락은 절대 에러로 안 나타납니다. 없는 걸 안 보는 데는 오류가 없습니다. 이게 감시판의 구조적 맹점입니다 — 감시가 자기 범위를 감시하지 않습니다.

여기서 선택지가 둘이었습니다. 당신이라면 어느 쪽을 하시겠습니까?

  1. 빠진 다섯 개를 손목록에 넣는다. 오늘 구멍이 오늘 막힌다. 5분이면 끝난다.
  2. 후보를 만드는 방식 자체를 고친다. 다음에 관례를 안 지키는 앱이 또 나와도 안 빠지게.

솔직히 말하면 1번을 반쯤 했습니다. 두 패턴의 합집합을 후보로 쓰도록 _ALT_PACKAGES를 분리해서 넣었고, 재실행하니 감시 대상이 22 → 27개, 그중 공개 26개로 잡혔습니다. 덤으로 앱 하나가 비공개에서 공개로 바뀐 것도 그 자리에서 처음 잡혔습니다.

이건 규칙을 하나 더 추가한 것이지, 추측을 없앤 게 아닙니다. 세 번째 작명 갈래가 생기면 또 조용히 빠집니다.

그런데 같은 날, 손 안 댄 면 하나는 맞아 있었습니다

재미있는 게 있었습니다. 웹 다섯 면을 전부 고치면서 확인만 하고 지나간 자리가 하나 있는데, 거기는 아무도 안 건드렸는데 이미 25개가 맞게 들어가 있었습니다.

숏폼 영상 끝에 붙는 스토어 배지입니다. 그 코드는 이렇게 생겼습니다.

def android_live(slug) -> bool:
    # 목록도 패턴 추측도 없다. 렌더할 때마다 스토어를 실제로 누른다.

목록이 없습니다. 렌더할 때마다 실제 스토어 응답을 보고 배지를 붙일지 말지 정합니다. 그래서 새 앱이 리뷰를 통과하면 아무도 등록하지 않아도 다음 렌더부터 배지가 붙습니다. 확인해보니 어제 문제가 됐던 다섯 개 전부 True였고, 안드로이드가 없는 앱 하나만 정확히 False였습니다.

같은 사실("이 앱이 스토어에 있나")을 세 가지 방식으로 답하고 있었던 셈입니다.

방식 새 앱이 생기면 누락되면
손으로 적은 목록 사람이 넣어야 보인다 조용함
이름 규칙으로 생성 관례를 지켜야 보인다 조용함
매번 원천 조회 저절로 보인다 구조상 없음

세 번째가 비싸 보이는데, 실제 비용은 하루 한 번 HTTP 요청 46개입니다. 제가 아낀 건 요청 46개였고, 대가로 산 건 3주간 13개 앱이 안 보인 것이었습니다.

자가진단 3개

  • 당신의 감시 봇이 보는 대상 개수와, 원천에 실제로 있는 개수를 지금 각각 세어보세요. 같습니까?
  • 그 목록이 이름 규칙으로 생성된다면, 규칙을 어긴 항목이 지금 하나라도 있습니까? 예외를 손으로 적어둔 적이 있다면, 그건 규칙이 이미 한 번 샜다는 증거입니다.
  • 대상 누락이 생겼을 때 그 봇은 어떤 신호를 냅니까? 아무 신호도 안 난다면 그 봇의 초록불은 "이상 없음"이 아니라 "내가 보는 범위 안에는 이상 없음"입니다.

결론

웹 다섯 면을 고친 건 하루치 노동이고 별 얘깃거리가 아닙니다. 남는 건 왜 3주 동안 아무도 말해주지 않았는가입니다.

이유는 제 감시판이 스토어에 묻지 않고 자기가 정한 작명 규칙에 물었기 때문입니다. 그리고 9월 4일에 한 번 새는 걸 봤으면서, 새는 걸 막지 않고 샌 물을 닦았습니다. 앱 하나를 손목록에 넣는 건 수정이 아니라 증상 처리였습니다. 같은 실수를 바로 전 글에서도 했더군요. 거기서는 상태 코드를 가져오고 원인을 안 가져왔습니다.

솔직한 부분: 지금 감시판도 여전히 추측합니다. 두 패턴의 합집합일 뿐 원천 조회가 아닙니다. 진짜 수정은 스토어가 아니라 콘솔 쪽 API로 앱 목록을 받아오는 건데, 그쪽은 앱 목록을 주는 엔드포인트가 없어서 지금은 방법이 없습니다. 그래서 이 글은 "고쳤습니다"가 아니라 "한 갈래 더 덮고, 여전히 추측 중입니다"가 정확합니다.

지금 딱 하나만 해보세요. 감시 스크립트를 열어서 대상 목록이 어디서 오는지 한 줄 찾아보시는 겁니다. 그게 리터럴이거나 f-string이면, 그 봇의 초록불에는 괄호가 하나 숨어 있습니다.

관련 글