대시보드가 네 개라는 건 탭이 네 개라는 뜻이었다
유튜브, SNS, 서치콘솔(GSC), 트래픽. 각각 필요할 때마다 따로 만든 대시보드가 네 개 있었습니다. 하나하나는 잘 돌았습니다. 문제는 "지금 전체가 어떤 상태인가"를 알려면 네 군데를 차례로 열어야 한다는 점이었습니다.
그래서 2026년 8월 4일, 네 개를 한 페이지로 요약하고 각 소스로 링크만 걸어주는 허브를 하나 만들었습니다. 커밋은 hub.py 159줄과 .gitignore 한 줄, 그게 전부입니다.
여기서 한 가지 묻고 싶습니다. 당신 프로젝트에서 "보려면 N군데를 열어야 하는 숫자"는 몇 개나 됩니까?
합치려고 보니 절반은 말을 할 줄 몰랐다
네 소스를 한 페이지에 올리려면 허브가 각 소스에서 숫자를 읽어와야 합니다. 그런데 네 개의 사정이 갈렸습니다.
두 개는 이미 살아 있는 서비스였습니다. 주소 뒤에 ?format=json을 붙이면 JSON을 돌려줍니다. 허브는 그걸 받아서 꺼내 쓰면 끝입니다.
나머지 두 개는 정적 리포트였습니다. 어떤 잡이 돌고 나서 파일 하나를 써두는 방식이라, 물어볼 상대가 없습니다. 허브가 알 수 있는 것은 두 가지뿐이었습니다. 파일의 수정 시각(mtime)으로 "이 숫자가 언제 것인지", 그리고 본문에 정규식을 걸어서 "숫자가 뭔지".
당신이라면? 정적 두 개에 JSON 엔드포인트를 먼저 붙이고 허브를 만드시겠습니까, 아니면 정규식으로 긁고 일단 넘어가시겠습니까?
내가 고른 쪽과 그 대가
저는 긁고 넘어갔습니다. 라이브 2개는 JSON으로, 정적 2개는 mtime과 정규식으로. 요약 한 페이지에 네 소스 링크. 바인딩은 tailnet IP의 8888 포트로 잡아서, 공개 인터넷이 아니라 제 기기들끼리만 보이게 했습니다.
이게 가장 짧은 길이었다는 데는 지금도 이견이 없습니다. 다만 이 선택이 무엇을 지불했는지는 분명히 적어둬야 합니다.
정규식은 리포트 포맷에 묶여 있습니다. 리포트를 만드는 쪽에서 문구나 줄 순서를 바꾸면, 허브는 에러를 내는 게 아니라 숫자를 못 찾거나 엉뚱한 숫자를 찾습니다. 그리고 mtime은 "파일이 다시 써졌다"는 사실만 말합니다. 그 안의 숫자가 맞는지, 잡이 중간에 실패하고 빈 파일을 남긴 건 아닌지는 말해주지 않습니다.
즉 이 허브는 네 개의 소스를 한 화면에 모았지만, 그중 절반은 "읽는다"기보다 "긁어서 추측한다"에 가깝습니다. 한 페이지로 모였다는 편리함이 그 차이를 가려버립니다.
자가진단 체크리스트
- 통합 페이지에 올라간 숫자 중, 원본 서비스에 직접 물어본 것과 파일을 긁어서 얻은 것을 구분해서 표시하고 있습니까?
- 긁어오는 쪽의 포맷이 바뀌면 "0"이나 "없음"이 아니라 "파싱 실패"로 드러나게 되어 있습니까?
- 파일 수정 시각을 신선도로 쓰고 있다면, 빈 파일이나 실패한 잡이 남긴 파일도 "최신"으로 보이지 않습니까?
솔직한 부분
이 글에서 확실한 사실은 커밋 하나뿐입니다. 159줄짜리 허브가 생겼고, 둘은 JSON으로, 둘은 mtime과 정규식으로 읽으며, tailnet 안에서만 뜹니다. 그 이후 정규식이 실제로 깨진 적이 있는지, 이 허브 덕에 제가 네 탭을 여는 습관을 정말 버렸는지는 기록이 없어서 말씀드릴 수 없습니다. 정적 두 소스에 JSON 엔드포인트를 붙이는 게 맞는 다음 단계라는 것도 압니다만, 그걸 언제 할지는 아직 정하지 못했습니다.