Rain Lag

아날로그 디버깅 여행 키트: 내 개발 환경이 없어도 버그를 잡는 법

기차, 비행기, 소파 위에서도 쓸 수 있는 작고 종이 기반의 디버깅 시스템을 설계하는 방법을 알아보세요. IDE, 멀티 모니터, 인터넷 없이도 버그를 체계적으로 추적하고 해결할 수 있습니다.

아날로그 디버깅 여행 키트: 내 개발 환경이 없어도 버그를 잡는 법

기차 안, 공항 라운지, 혹은 소파 위. 노트북은 있는데 인터넷은 애매하게 느리고, 평소 쓰던 멀티 모니터와 빵빵한 개발 환경은 없다. 프로파일러도 없고, 로그도 제한적이고, 디버거는 아예 없을 수도 있다.

그래도 버그는 머릿속에서 떠나질 않고, 어떻게든 진척을 내고 싶다.

이럴 때 빛을 발하는 것이 바로 아날로그 디버깅 여행 키트다. 일부러 설계한, 휴대 가능한 종이 기반 시스템으로, 마치 평소 개발 환경을 그대로 들고 다니는 것처럼—어떨 땐 오히려 그 이상으로—버그를 논리적으로 추적할 수 있게 해준다.

이 글에서는 왜 종이가 디버깅에 그렇게 잘 맞는지, 여행 키트에 무엇을 넣어야 하는지, 그리고 완전히 종이만으로 반복 가능한 “과학적인 디버깅 워크플로우”를 돌리는 방법을 소개한다.


왜 굳이 종이로 디버깅을 해야 할까?

점점 더 종이 없는, 자동화된 세상에서 종이는 다소 원시적으로 느껴질 수 있다. 하지만 디버깅이라는 맥락에서는 IDE가 줄 수 없는 장점이 있다.

  • 마찰이 없다 – 컨텍스트 전환도, 창 정렬도, 앱 렉도 없다. 펜이 종이에 닿는 순간 바로 생각이 기록된다.
  • 방해 요소가 없다 – 슬랙 알림도, 트위터 탭도, 이메일 팝업도 없다. 오직 나와 문제만 남는다.
  • 배터리와 무관하다 – 기차, 비행기, 노트북 배터리가 간당간당해도… 종이는 계속 작동한다.
  • 스택에 구애받지 않는다 – Rust든, Python이든, Kotlin이든, 임베디드 C든 상관 없다. 생각하는 패턴은 비슷하다.
  • 공간 제약이 없다 – 타임라인, 트리, 매트릭스 등 어떤 배치든 마음대로 그릴 수 있다. 편집기와 싸울 필요가 없다.

종이에 **콜 스택(call stack), 데이터 흐름(data flow), 상태 전이(state transition)**를 그려 보면, 디버거로 한 줄씩 따라갈 때는 놓치기 쉬운 패턴과 불일치가 눈에 들어온다. 코드를 “실행”하는 게 아니라, 머릿속에 있는 정신적 모델을 바깥으로 끄집어내서 현실과 비교하는 셈이다.


핵심 아이디어: 디버깅을 과학적인 프로세스로 보기

효과적인 디버깅은 기본적인 과학적 탐구 사이클과 놀라울 만큼 잘 맞아떨어진다.

  1. 버그와 그 증상관찰한다.
  2. 무엇이 잘못됐을지에 대한 가설을 세운다.
  3. 그 가설을 검증하기 위한 실험(로그 추가, 테스트, 재현)을 설계한다.
  4. 실험을 실행하고 결과를 기록한다.
  5. 결과에 따라 가설을 수정하고 반복한다.

아날로그 키트는 이 과정을 위한 휴대용 실험 노트라고 볼 수 있다. 머릿속에만 떠다니거나, 여기저기 흩어진 텍스트 파일에 적어 두는 대신에:

  • 각 가설과 테스트를 명확하게 적어 두고,
  • 이미 시도해 본 아이디어를 추적하며,
  • 무엇을 언제, 어떤 근거로 알게 되었는지 타임라인을 세우고,
  • 마지막에는 다음 버그에도 도움이 될 작은 “포스트모템”까지 남긴다.

결과적으로, 풀 세팅이 아닌 상황에서도 구조화된 방식으로 실제 진전을 낼 수 있다.


아날로그 디버깅 여행 키트에 무엇을 넣을까

많이 필요하지 않다. 목표는 휴대 가능하고, 단순하며, 반복 가능한 구성이다.

다음은 최소한이지만 강력한 세트업이다.

1. 인덱스 카드

3"×5" 또는 4"×6" 인덱스 카드를 하나의 생각 단위로 사용한다.

  • 카드 한 장에 하나의 가설 (예: “304 응답일 때 캐시가 무효화되지 않는 것 같다”).
  • 카드 한 장에 하나의 실험 (예: “핸들러 X의 캐시 쓰기 주변에 로그를 추가해 본다”).
  • 카드 한 장에 하나의 핵심 관찰 (예: “Request ID 1234: 200 OK인데 헤더 X가 비어 있음”).

인덱스 카드는 글을 짧게 쓰도록 강제하고, 아이디어를 섞고, 모으고, 버리기 쉽게 해 준다.

2. 도트 그리드 용지나 작은 노트

도트 그리드 페이지는 다음에 특히 좋다.

  • 콜 스택 스케치 – 누가 누구를 어떤 순서로 호출하는지 시각화.
  • 데이터 흐름 다이어그램 – 데이터가 서비스, 큐, 캐시를 어떻게 통과하는지.
  • 상태 머신 – 객체나 요청이 어떤 상태를 거치고, 언제 전이되는지.
  • 타임라인 – 요청/응답 시퀀스, 비동기 이벤트 순서, 레이스 컨디션.

도트는 어느 정도의 직선을 그릴 수 있는 구조를 주면서도 레이아웃을 제약하지 않는다.

3. 색 펜 또는 형광펜

색깔 몇 개만 있어도 가독성이 확 달라진다.

  • 검정/파랑 – 일반 메모, 코드 조각, 함수 이름.
  • 빨강 – 에러, 예상 밖의 동작, 모순.
  • 초록 – 확인된 사실, 증거로 뒷받침된 내용.
  • 주황/보라 – 가설, 열린 질문, “미지의 것들”.

색을 나누기만 해도, 그냥 끄적거린 페이지가 길 찾기 쉬운 지도로 바뀐다.

4. 포스트잇(스티키 노트)

작은 포스트잇은 이런 용도로 좋다.

  • 특정 페이지에 “진행 중인 버그”, “나중에 다시 보기” 같은 태그 붙이기.
  • 의존 관계 표시 (예: “X 배포 전까지 블로킹”).
  • 특정 가설 카드를 여러 다이어그램 옆에 임시로 “핀” 해 두기.

페이지를 갈아엎지 않고도 레이어를 하나 더 올릴 수 있는 가벼운 수단이다.

5. 간단한 템플릿 시스템

프로세스를 재사용 가능하게 만들려면, 손으로 금방 그릴 수 있는 아주 가벼운 템플릿을 정해 두는 게 좋다. 인쇄된 양식까지는 필요 없고, 10초면 그릴 수 있는 일관된 레이아웃이면 된다.

예를 들면:

  • 가설 카드 템플릿 (인덱스 카드)

    • 맨 위 줄: HYPOTHESIS #n + 짧은 제목
    • 중간: “나는 __라고 믿는다, 그 이유는 __ 때문이다.”
    • 아래: “다음이 관찰되면 이 가설은 기각된다: __”
  • 실험 카드 템플릿

    • 위: EXPERIMENT #n
    • 섹션: “변경 / 테스트 / 기대 결과 / 실제 결과 / 결론 (Pass/Fail)”
  • 관찰 로그 템플릿 (노트 한 페이지)

    • 왼쪽 여백: 시간 / 환경 / 버전
    • 본문: 관찰 내용 상세
    • 오른쪽 여백: 태그 (예: cache, auth, race, db 등)

작은 구조가 큰 효율을 가져온다.


반복 가능한 종이 기반 디버깅 워크플로우

이제 이 키트를 어디서든 실행할 수 있는 일관된 워크플로우로 만드는 한 가지 방법을 살펴보자.

1. 버그 개요 페이지부터 시작하기

새 페이지를 열고 다음을 적는다.

  • 버그 이름: 짧고 설명적인 라벨.
  • 환경: prod/staging/local, 버전/커밋 해시.
  • 증상: 사용자/시스템이 겪는 현상, 가능한 한 그들의 표현으로.
  • 영향도: 심각도, 빈도, 영향받는 사용자 범위.
  • 재현 가능성: 항상 / 가끔 / 불명.

이 페이지가 이후 모든 내용의 앵커 페이지가 된다. 다른 페이지를 볼 때도 언제든 돌아와서 전체 맥락을 상기할 수 있다.

2. 고수준 시스템 맵 그리기

다음 도트 그리드 페이지에, 이번 버그와 관련된 필요한 컴포넌트만 간단히 그린다.

  • 진입점 (UI, API 게이트웨이, CLI 명령 등)
  • 주요 서비스와 데이터베이스
  • 관련된 캐시/큐/서드파티 시스템

그리고 실패하는 요청 또는 시나리오 하나를 이 맵 위에 따라가 보며 질문한다.

  • 어디에서 문제가 발생할 수 있을까?
  • 어디에는 로그가 있고, 어디에는 없는가?
  • 상태나 타이밍에 대해 우리가 어떤 가정을 하고 있는가?

문제가 생길 법한 지점을 작은 동그라미 숫자(1, 2, 3...)로 표시한다. 이 번호들이 이후 가설의 씨앗이 된다.

3. 혼란스러운 지점을 가설로 바꾸기

머릿속에 “아마 ~~ 때문일지도…”라는 생각이 스치면, 인덱스 카드를 한 장 꺼낸다.

  • 명확한 가설 문장을 적고,
  • 왜 그런 생각을 하는지 이유를 짧게 적으며,
  • 어떤 증거가 나타나면 이 가설이 기각되는지를 구체적으로 적는다.

예:

HYPOTHESIS #3
캐시 엔트리가 만료되진 않았지만, 실제로는 오래된(stale) 값일 때 버그가 발생한다고 생각한다. 그 이유는 로그에서 updated_at과 캐시 타임스탬프 간에 불일치가 보였기 때문이다. 만약 캐시가 완전히 비어 있는(cold) 상태에서도 동일한 버그가 재현된다면 이 가설은 기각된다.

이렇게 하면 애매하고 손에 잡히지 않는 느낌의 추측이 아니라, 정확하고 반증 가능(falsifiable)한 주장이 된다.

4. 실험을 설계하고 로그로 남기기

가설에 따라 필요한 실험은 다양하다.

  • 수상한 함수 주변에 로그를 추가한다.
  • 최소 재현 스크립트를 만든다.
  • 조건을 조금씩 바꿔가며 동시에 여러 요청을 보내 본다.
  • 특정 헤더, 페이로드, 타이밍 정보를 수집한다.

각 실험마다 실험 카드를 만든다.

  • 무엇을 바꾸거나 시도할 것인지
  • 가설이 맞다면 어떤 결과를 예상하는지
  • 실제로 무엇이 관찰되었는지
  • 단순한 Pass/Fail 판단

이 카드를 만들어 두면, 다시 전체 개발 환경으로 돌아갔을 때 다시 생각할 필요 없이 바로 실행만 하면 된다.

5. 타임라인 페이지 유지하기

동시성, 레이스 컨디션, 플래키한(flaky) 버그에는 타임라인 페이지가 특히 유용하다.

  • 가로 축은 시간을, 세로로는 각 액터/서비스 별 레인을 긋는다.
  • 이벤트를 박스로 표시하고, 사이를 화살표로 연결한다.

단서를 모을수록 타임라인을 업데이트한다.

  • “T0에 요청 전송, T0+200ms에 응답 도착”
  • “T0+150ms에 백그라운드 잡이 실행되어 캐시를 무효화해야 함”

이렇게 그려 두면 “읽기보다 무효화가 먼저 일어나야 한다” 같은 기대와 실제 순서의 불일치가 눈으로 바로 보인다.

6. 마지막에 한 페이지짜리 포스트모템 쓰기

루트 원인을 찾았으면, 마이크로 포스트모템을 한 페이지에 정리한다.

  • 루트 원인: 실제로 무엇이 잘못됐는가.
  • 트리거 조건: 어떤 상황/입력에서 드러났는가.
  • 찾기 어려웠던 이유: 로그 부재, 숨은 가정, 오해를 부른 증상 등.
  • 핵심 인사이트: 설계나 프로세스 측면에서 얻은 교훈.
  • 예방 조치: 테스트, 모니터링, 패턴 개선 등 앞으로의 대응.

이렇게 쌓인 페이지들은 시간이 지나면 개인 디버깅 플레이북이 된다. 새로운 문제가 “어디서 많이 본 느낌”일 때, 예전 사례를 훑어 보며 바로 힌트를 얻을 수 있다.


아날로그는 디지털 도구를 어떻게 보완할까

아날로그 여행 키트는 디버거나 로그를 대체하는 것이 아니다. 오히려 여러 디지털 소스에서 나온 조각난 단서들을 엮어 주는 사고 보조 도구다.

  • IDE는 브레이크포인트와 스택 트레이스를 준다. 노트는 그걸 구조화하고 기억하게 해 준다.
  • 로그는 날것의 이벤트를 던져준다. 종이는 그것을 이야기 구조로 재배열하게 해 준다.
  • 모니터링 도구는 스파이크를 보여준다. 다이어그램은 그 스파이크를 특정 플로우나 상태와 연결해 준다.

종이는 툴에 구애받지 않기 때문에, 다음과 같은 다양한 상황에서 활용할 수 있다.

  • 여러 마이크로서비스가 얽힌 백엔드 버그
  • 프론트엔드 상태 동기화 문제
  • 모바일/데스크톱의 오프라인 엣지 케이스
  • 임베디드 또는 IoT 환경의 타이밍 이슈

코드는 달라도, 그 아래에서 돌아가는 추론 패턴은 대부분 비슷하다.


시작하기: 작은 키트를 만들고 딱 한 번만 써 보기

이걸 거창하게 시작할 필요는 없다. 우선은 이렇게만 해도 충분하다.

  1. 인덱스 카드 몇 장, 도트 그리드 용지나 작은 노트, 펜 2–3개를 준비한다.
  2. 얇은 폴더, 지퍼 파우치, 혹은 노트북 슬리브 뒤쪽 같은 곳에 넣어 둔다.
  3. 다음에 버그가 기차나 소파까지 쫓아올 때, 이 워크플로우를 딱 한 번만 돌려 본다.
    • 버그 개요 페이지
    • 시스템 맵
    • 몇 장의 가설 카드와 실험 카드
    • 해결 후 짧은 포스트모템 한 페이지

그다음에는 이 템플릿들을 본인 스타일에 맞게 조금씩 바꿔 가면 된다.

시간이 지나면, 아날로그 디버깅 여행 키트는 마치 내 뇌의 확장처럼 느껴질 것이다. 멀티 모니터도, 풀 세팅 IDE도 없이, 어디서든 고집 센 버그를 길들이게 도와주는 휴대용, 배터리 프리 디버깅 시스템이 된다.

아날로그 디버깅 여행 키트: 내 개발 환경이 없어도 버그를 잡는 법 | Rain Lag