본문 바로가기
책상 노트 책상 노트
실무자가 실제로 굴려본 업무도구·업무 자동화 기록

알림 받으려 만든 봇을 3주 만에 무음으로 돌린 이유

읽는 시간 약 11분

자동화 작업이 끝나면 텔레그램으로 알려주는 봇을 만들었습니다. 처음 일주일은 신기했고, 둘째 주부터는 소리를 꺼뒀고, 3주째 되는 날 봇이 보낸 장애 알림을 놓쳐서 서버가 아홉 시간 동안 멈춰 있었습니다. 알림을 놓치지 않으려고 만든 물건이 알림을 놓치게 만든 셈입니다.

지금도 같은 봇을 쓰고 있습니다. 다만 하루에 오는 메시지가 140건에서 여섯 건 안팎으로 줄었고, 그 뒤로 장애를 놓친 적은 없습니다. 무엇을 잘못 만들었고 어떤 규칙으로 바꿨는지를 적어둡니다.

왜 텔레그램이었나

네 개 법인의 재무를 보다 보니 밤이나 새벽에 돌아가는 자동 작업이 꽤 됩니다. 은행 거래내역 정리, 세금계산서 메일 수집, 매장 매출 집계, 블로그 예약 발행 같은 것들이 정해진 시간에 크론으로 돌아갑니다. 문제는 이게 돌았는지 안 돌았는지를 아침에 제가 하나씩 열어봐야 확인이 된다는 점이었습니다.

작업 로그는 서버 안에 쌓이고 있었지만, 로그를 보려면 서버에 붙어야 합니다. 출근길 지하철에서 확인할 방법이 없었습니다. 그래서 작업이 끝나면 결과를 휴대폰으로 보내주는 창구가 필요했고, 이미 개인적으로 쓰던 텔레그램이 봇 만들기가 가장 쉬웠습니다. 카카오톡은 사업자 채널 승인이 필요했고, 문자는 건당 비용이 나갑니다. 텔레그램 봇은 토큰 하나 받고 파이썬 스크립트 열 줄이면 메시지가 갔습니다.

첫 버전을 만드는 데 걸린 시간은 두 시간 정도였습니다. 텔레그램에서 봇 토큰을 받고, 제 계정의 채팅 ID를 알아내고, 크론 스크립트 끝에 메시지 전송 함수를 한 줄씩 붙이는 작업이었습니다. 그중 한 시간은 채팅 ID를 찾는 데 썼습니다. 봇에게 먼저 말을 걸어야 ID가 잡힌다는 걸 몰라서 빈 응답만 계속 받았는데, 이건 나중에 다른 사람에게 알려줄 때도 같은 자리에서 걸리는 걸 보고 흔한 함정이라는 걸 알았습니다.

어쨌든 첫 메시지가 휴대폰에 도착했을 때는 꽤 만족스러웠습니다. 문제는 그 뒤 3주였습니다.

알림 봇 첫 버전을 만드는 데 든 시간과 작업 수를 숫자로 정리한 도해

첫 3주: 모든 것을 보고하게 만든 결과

만들고 나니 욕심이 생겼습니다. 작업이 끝났다는 것만 알리면 아쉬우니 성공도 알리고, 시작도 알리고, 중간 진행도 알리게 했습니다. 크론 작업 열한 개가 전부 시작과 종료를 보고하고, 여기에 서버 상태 점검이 10분마다 한 줄씩 붙었습니다.

첫 주에 하루 메시지 수를 세어보니 평균 140건이었습니다. 그중 실제로 제가 봐야 했던 메시지는 하루 두세 건이었습니다. 나머지는 “정상 종료”, “확인 완료”, “변동 없음” 같은 말이 시간만 바꿔가며 반복되는 것들이었습니다.

둘째 주에 알림 소리를 끄고 진동도 껐습니다. 봇 대화방을 열어보는 횟수가 하루 열 번에서 두세 번으로 줄었고, 셋째 주에는 아침에 한 번 스크롤로 훑는 게 전부가 됐습니다. 그리고 그 주 목요일 새벽 2시 40분에 서버 상태 점검이 “응답 없음”을 보냈습니다. 그 메시지는 “변동 없음” 서른 건 사이에 끼어 있었고, 저는 아침 훑기에서 그걸 지나쳤습니다. 오전 11시에 매장 쪽에서 집계표가 안 왔다는 연락을 받고서야 알았습니다.

복구 자체는 20분이면 끝나는 일이었습니다. 아홉 시간 동안 아무도 몰랐다는 게 문제였습니다.

첫 주부터 서버가 아홉 시간 멈춘 것을 알게 되기까지의 경과를 단계로 정리한 도해

복기: 알림의 수가 아니라 등급이 없었습니다

처음에는 메시지가 너무 많은 게 문제라고 봤습니다. 그래서 절반을 줄이면 될 것 같았는데, 곰곰이 따지니 수의 문제가 아니었습니다. 140건 중 하나가 장애였다면 그 하나만 다르게 보였어야 합니다. 그런데 저는 성공 보고와 장애 보고를 같은 방, 같은 형식, 같은 소리로 받게 만들었습니다. 봇 입장에서는 “정상 종료”와 “응답 없음”이 똑같은 한 줄 문자열이었습니다.

그러니까 없던 것은 등급이었습니다. 이 알림이 지금 봐야 하는 것인지, 아침에 봐도 되는 것인지, 안 봐도 되는 것인지를 메시지 자체가 말해주지 않았습니다. 사람이 140건을 매번 읽어서 분류하라는 구조였고, 그 구조는 사흘을 못 갔습니다.

한 가지 더 걸린 게 있습니다. 성공 알림은 사실 정보가 아니었습니다. 열한 개 작업이 매일 성공한다는 걸 저는 이미 알고 있었습니다. 알아야 할 것은 실패한 날뿐인데, 성공을 보고받으면 안심이 된다는 이유로 붙여뒀던 겁니다. 안심을 위한 알림이 진짜 알림을 덮은 셈입니다.

바꾼 규칙 네 가지

3주차 사고 다음 날 봇 설정을 전부 걷어내고 규칙을 다시 썼습니다. 코드를 고친 시간보다 규칙을 정하는 데 시간이 더 들었습니다. 열한 개 작업을 하나씩 놓고, 이 작업이 실패하면 몇 시간 안에 알아야 하는지를 적어봤습니다. 은행 거래내역 정리는 다음 날 아침에 알아도 됩니다. 매장 매출 집계는 매장 오픈 전에 알아야 하고, 서버 자체가 멈춘 건 즉시 알아야 합니다. 이렇게 적어보니 즉시 알아야 하는 것은 열한 개 중 두 개뿐이었습니다. 나머지 아홉 개는 아침에 몰아서 봐도 아무 일이 없는 것들이었는데, 3주 동안 그 아홉 개가 실시간으로 저를 불러댔던 겁니다.

이렇게 정리한 작업별 확인 시한을 바탕으로 정한 규칙이 아래 네 가지입니다.

  • 성공은 보고하지 않습니다. 대신 하루에 한 번, 아침 7시 30분에 “어제 밤 작업 열한 개 중 열한 개 정상”이라는 한 줄만 옵니다. 정상이 아닌 게 있으면 그 줄에 작업 이름이 붙습니다.
  • 장애는 별도 방으로 보냅니다. 텔레그램 방을 두 개로 나눠서 하나는 요약 전용, 하나는 장애 전용으로 뒀습니다. 장애 방만 소리를 켜두면 나머지는 무음이어도 됩니다.
  • 장애 방 메시지에는 첫 줄에 무엇을 해야 하는지가 들어갑니다. “서버 응답 없음”이 아니라 “서버 응답 없음, 재시작 필요, 매장 집계 09:00 전 확인”처럼 다음 행동까지 적히게 했습니다. 새벽에 잠결에 봐도 판단이 서야 합니다.
  • 같은 장애가 반복되면 한 번만 보냅니다. 10분마다 점검이 도는데 응답이 없으면 여섯 번 연속으로 같은 알림이 왔습니다. 첫 번째만 보내고, 복구되면 “복구됨” 한 건을 보내는 식으로 바꿨습니다.
항목첫 3주지금
하루 메시지 수약 140건6건 안팎
방 구성하나요약방, 장애방 분리
성공 알림작업마다아침 요약 한 줄
장애 알림반복 전송첫 발생 1건, 복구 1건
소리전부 켬 후 전부 끔장애방만 켬
첫 3주와 규칙을 바꾼 뒤의 알림 방식을 좌우로 비교한 도해

바꾸고 나서 생긴 일

규칙을 바꾼 뒤 두 달 동안 장애 방에 메시지가 온 것은 네 번입니다. 네 번 다 30분 안에 확인했고, 그중 두 번은 새벽이었지만 소리가 울려서 일어났습니다. 첫 3주에는 아홉 시간을 몰랐던 걸 생각하면 이 차이가 이 글의 전부입니다.

요약 방은 아침에 한 줄 읽고 끝입니다. 다만 요약 한 줄이 “열한 개 중 열 개 정상”으로 온 날이 있었는데, 그날은 정상이 아닌 작업의 원인을 확인하려고 장애 방을 열었고 거기에 새벽에 온 원인이 적혀 있었습니다. 두 방이 각자 역할을 하는 구조가 그날 처음 제대로 보였습니다.

예상 못 한 부작용도 하나 있었습니다. 성공 알림이 사라지자 처음 며칠은 불안했습니다. 조용하면 봇이 죽은 건지 정상인 건지 구분이 안 됐던 겁니다. 그래서 아침 요약 한 줄이 안 오면 그것 자체를 장애로 치는 규칙을 추가했습니다. 요약이 오지 않는 날은 봇 자체가 죽은 날이고, 이건 다른 경로로 알아야 하니 서버와 별개인 개인 PC에서 요약 도착 여부를 확인하는 작업을 하나 더 걸었습니다. 봇을 감시하는 봇이 생긴 셈인데, 구조가 우스워 보여도 실제로 한 번 잡아냈습니다. 서버 업데이트 뒤에 텔레그램 라이브러리 버전이 어긋나서 전송 함수가 조용히 실패하던 날이었고, 요약이 안 왔다는 알림이 아니었으면 며칠은 모르고 지나갔을 겁니다.

같은 방식을 매장 쪽 직원에게도 하나 열어줬습니다. 매출 집계가 오픈 전에 안 만들어지면 그 직원의 텔레그램으로 바로 가게 한 건데, 이때는 제가 겪은 실패를 그대로 반영해서 처음부터 실패만 보내게 했습니다. 직원은 봇이 조용한 게 정상이라는 걸 한 번 설명 듣고 바로 받아들였습니다. 성공 보고를 받아본 적이 없으니 그게 없어서 불안할 일도 없었던 겁니다. 처음부터 그렇게 만들었으면 저도 3주를 아꼈을 텐데, 직접 겪지 않았으면 그 규칙이 왜 필요한지도 몰랐을 겁니다.

알림 문구를 고치는 데 든 시간

규칙 네 가지 중 셋째, 장애 메시지 첫 줄에 다음 행동을 적는 것이 가장 오래 걸렸습니다. 코드로는 문자열 하나 바꾸는 일인데, 무슨 문장을 넣을지 정하는 게 문제였습니다. 작업 열한 개마다 실패했을 때 제가 실제로 무엇을 하는지를 적어보니, 절반은 제가 그 자리에서 바로 말할 수 없었습니다. 서버가 멈추면 재시작이지만, 세금계산서 수집이 실패하면 메일 서버 문제인지 파싱 문제인지에 따라 할 일이 다릅니다.

결국 실패 종류를 둘로 나눴습니다. 원인이 하나로 정해지는 실패는 행동을 문장으로 박았고, 원인이 여럿인 실패는 “로그 확인 필요, 경로는 이곳”으로 두고 로그 파일 위치를 같이 보내게 했습니다. 새벽에 휴대폰으로 로그를 읽을 일은 없지만, 아침에 자리에 앉아 어디를 열어야 하는지는 정해져 있는 셈입니다. 이 문구 열한 줄을 정하는 데 한 시간 반이 들었고, 지난 두 달 장애 네 건 중 세 건이 이 문구대로 처리됐습니다. 나머지 한 건은 문구가 가리키는 원인이 아니어서 결국 로그를 봤는데, 그 뒤 그 작업의 문구를 고쳤습니다. 알림 문구도 한 번 정하고 끝이 아니라 장애가 날 때마다 다듬는 물건이라는 걸 그때 알았습니다.

알림을 편집할 때 보는 네 가지

  • 알림은 받는 사람이 다음에 무엇을 할지 정해주는 것만 보냅니다. 할 일이 없는 알림은 정보가 아니라 소음입니다.
  • 성공은 세지 않고 실패만 셉니다. 매일 성공하는 일의 성공 보고는 실패 보고를 덮는 데만 쓰입니다.
  • 알림에는 등급을 붙이고, 등급마다 도착 경로를 다르게 합니다. 같은 방에 다 넣으면 사람이 매번 분류하게 되고, 그 분류는 오래 못 갑니다.
  • 조용한 것과 죽은 것을 구분할 장치를 하나 둡니다. 하루 한 줄이라도 정기적으로 오는 것이 있어야 침묵을 신뢰할 수 있습니다.

봇을 만든 두 시간보다 알림 규칙을 정한 반나절이 더 값어치가 있었습니다. 알림은 기술이 아니라 편집이라는 걸, 아홉 시간 멈춘 서버가 가르쳐준 셈입니다.

책상 노트 운영자
함께 보면 좋은 글
error: Content is protected !!