Rain Lag

다섯 가지 질문 디버그 다이어리: 모든 버그 수정을 한 단계 끌어올리는 작은 습관

단순한 다섯 가지 질문 디버깅 다이어리가 어떻게 모든 버그를 학습 기회로 바꾸고, 반복 실수를 줄이며, 나와 팀을 위한 가벼운 지식 베이스를 쌓게 해주는지 살펴봅니다.

소개

대부분의 개발자는 본능적으로 디버깅합니다. 코드를 뚫어져라 쳐다보고, console.log 몇 개 뿌려 보고, 여기저기 찔러 보다가 뭔가 움직이면 그 상태로 고치고 배포한 뒤 다음 일로 넘어갑니다.

이 방식도 어느 정도는 잘 작동합니다. 그러다 같은 종류의 버그가 다시 나타날 때까지는요. 그리고 또 다시. 스택 트레이스는 매번 달라 보이지만, 뿌리는 같습니다.

문제는 우리가 버그를 고칠 줄 모르는 게 아니라 고친 버그로부터 체계적으로 배우지 않는다는 것입니다.

작지만 꾸준한 하나의 의식이 이걸 바꿀 수 있습니다. 바로 다섯 가지 질문 디버그 다이어리입니다. 버그 하나당 몇 분이면 충분하지만, 몇 주, 몇 달이 지나면 조용히 다음을 끌어올립니다.

  • 디버깅 실력
  • 설계·아키텍처 판단
  • 팀이 공유하는 지식

이건 사소한 오타에도 매번 무거운 프로세스나 포스트모텀을 붙이자는 얘기가 아닙니다. 평소 워크플로 안에 자연스럽게 들어오는, 가벼운 회고 루프를 만드는 이야기입니다.

이제 그 다섯 가지 질문을 하나씩 살펴보며, 더 나은 디버깅과 어떻게 연결되는지 보겠습니다.


다섯 가지 질문 디버그 다이어리

버그를 고친 직후에, “아 저거 진짜 힘들었는데…” 하는 기억이 사라지기 전에, 아래 다섯 가지 질문에 답을 남깁니다.

  1. 뭐가 어떻게 망가졌고, 겉으로 어떻게 드러났는가?
  2. 진짜 근본 원인은 무엇이었는가? (구체적으로)
  3. 어떤 데이터, 설정, 환경에 대한 가정이 틀렸는가?
  4. 실제로 어떻게 버그를 찾았는가? (먹힌 것, 안 먹힌 것)
  5. 다음에 이 부류의 버그가 덜 나오게 하려면 무엇을 바꿀 수 있는가?

정말 이게 전부입니다.

각 질문은 입력, 설정, 머릿속 모델을 다시 점검하게 만듭니다. 이 세 군데가 바로 대부분의 “이상한” 버그가 숨어 있는 곳입니다.

이제 각 질문을 조금 더 풀어 보면서, 구체적인 체크 포인트와 습관으로 연결해 보겠습니다.


1. 뭐가 어떻게 망가졌고, 겉으로 어떻게 드러났는가?

대부분의 버그 제보는 모호합니다. “안 돼요”, “결제 실패함”, “페이지가 계속 로딩됨”.

다이어리의 첫 줄은 추측이 아니라 관찰 가능한 증상으로 시작해야 합니다.

  • 정확한 에러 메시지나 스택 트레이스
  • 사용된 URL 또는 기능
  • 사용자가 실제로 수행한 행동 순서
  • 환경 (프로덕션/스테이징/로컬, OS, 브라우저나 클라이언트, 버전 정보 등)

이걸 적다 보면 스스로에게 이렇게 묻게 됩니다.

정확히 무엇을, 어떤 조건에서 봤는가?

예시 기록:

증상: 프로덕션 환경에서만 체크아웃 페이지에서 할인 코드 적용 시 500 Internal Server Error 발생. 스테이징에서는 정상 동작.
상황: 프로덕션, Node 18, 할인 코드 BLACKFRIDAY2025, 첫 구매 고객에 한해 발생.

이 정도만 써도 이미 많은 걸 해낸 겁니다. 적지 않은 버그들이 재현 방법을 분명히 적지 않아서 오래 방치됩니다.


2. 진짜 근본 원인은 무엇이었는가? (구체적으로)

“API가 실패했다”는 근본 원인이 아닙니다.

“할인 서비스가 길이 10자를 초과하는 코드를 검증 과정에서 거부해서 null을 반환했다”는 수준이어야 합니다.

다이어리에는 실패를 일반인도 이해할 수 있는 평이한 언어로 설명할 수 있을 정도로, 하나의 명확하고 구체적인 문장으로 적습니다.

  • "price 필드는 항상 number일 거라고 가정했는데, 프로덕션에서는 string으로 들어왔다."
  • "크론 잡이 앱 설정과 인프라 설정 양쪽에 잡혀 있어서 스케줄이 두 번 실행됐다."
  • "네트워크 타임아웃은 처리했지만, DNS 해석 오류는 처리하지 않았다."

이렇게까지 풀어서 적으려다 보면, 종종 반복되는 패턴이 눈에 들어옵니다.

  • “null/undefined 처리를 자주 놓친다.”
  • “서드파티 데이터 포맷을 너무 ‘믿고’ 쓴다.”
  • “타임존 변환을 자꾸 빼먹는다.”

이런 패턴이 바로 장기적으로 개선해야 할 부분입니다.


3. 어떤 데이터, 설정, 환경에 대한 가정이 틀렸는가?

놀랄 만큼 많은 “코드 버그”는 사실 데이터, 설정(config), 실행 환경(environment) 문제입니다.

이 질문은 이 세 가지를 체계적으로 훑어보게 합니다.

a) 입력, 출력, 엣지 케이스

스스로에게 이렇게 물어봅니다.

  • 실제 런타임 입력값을 확인했는가?
    (실제 payload, request body, 파일, 사용자 입력, DB 레코드 등)
  • 출력 결과가 기대와 일치하는지 확인했는가?
    (HTTP status code, 응답 body 구조, side effect, DB 변경 내용 등)
  • 엣지 케이스를 테스트했는가?
    • 빈 리스트, null, 0, 아주 큰 값, 비 ASCII 문자, 특이한 날짜 등등

자주 나오는 문제들:

  • API가 null을 허용하는데, 우리 코드는 그걸 전혀 예상하지 않았다.
  • UI가 null 대신 빈 문자열을 보내고 있었다.
  • “드문” 케이스(복수 할인, 이메일 없음, 만료된 토큰 등)가 전혀 처리되지 않은 분기를 밟았다.

b) 설정, 환경 변수, 외부 의존성

이제 코드 주변을 봅니다.

  • 설정 파일: feature flag, YAML/JSON 설정, 빌드 설정
  • 환경 변수: 누락, 오타, 값이 다름, 스테이징과 프로덕션 간 차이
  • 외부 의존성: 서비스 다운, 새 버전 배포, rate limit, API 스펙 변경 등

자문해볼 질문들:

  • 버그가 발생한 그 환경에서의 설정을 실제로 확인했는가?
  • 로컬 / 스테이징 / 프로덕션 설정 간에 차이가 있는가?
  • 우리가 의존하던 기본값(default)이 어느 순간 바뀌지는 않았는가?

예시 기록:

틀린 가정: DISCOUNT_SERVICE_URL이 스테이징과 프로덕션에서 동일하게 설정돼 있다고 생각했다.
현실: 프로덕션 환경 변수는 예전 마이크로서비스 버전을 바라보고 있었고, 그 버전은 JSON 구조가 조금 달랐다.

이런 내용을 남겨 두면, 다음번엔 설정을 맨 마지막이 아니라 제일 먼저 확인하게 됩니다.


4. 실제로 어떻게 버그를 찾았는가? (먹힌 것, 안 먹힌 것)

여기서는 디버깅 결과가 아니라 과정을 기록합니다.

특히 다음을 적습니다.

  • 어떤 단계가 실제로 도움이 되었는가?
  • 어떤 시도는 시간만 날렸는가?
  • 어떤 도구나 기법이 결정적인 단서를 줬는가?

단순하지만 목표가 분명한 도구를 써라

모든 버그에 거창한 observability 도구가 필요한 건 아닙니다. 오히려 가장 빠른 길은 이런 것들인 경우가 많습니다.

  • 핵심 변수 값을 출력하는 console.log / print
  • 특정 함수나 엔드포인트만 두드려 보는 작은 “probe” 스크립트나 일회성 테스트
  • 필요한 행만 보는 간단한 DB 쿼리
  • 브라우저 개발자 도구 / Network 탭

다이어리에는 이렇게 적을 수 있습니다.

코드만 읽으면서 추측하는 데 45분을 썼다.
실제로 도움이 된 건 console.log("discount payload", payload)를 찍고 스테이징과 프로덕션 요청을 diff 해 본 것.

또는:

실패한 payload로 할인 서비스를 호출하는 작은 스크립트를 따로 만들어서 때려 보며 범위를 좁혔다. 그 과정에서 프로덕션에서는 code: "BLACKFRIDAY2025"가 경우에 따라 숫자로 내려오는 걸 발견.

이런 기록이 쌓이면, 시간이 지날수록 어떤 디버깅 방법이 지속적으로 효율적인지 보이기 시작합니다. 그게 곧 나만의 디버깅 스타일이 성장하는 과정입니다.


5. 다음에 이 부류의 버그가 덜 나오게 하려면 무엇을 바꿀 수 있는가?

이 질문이 가장 중요합니다.

이번 버그만 막는 게 아니라, 형제·사촌 버그들의 재등장 확률을 줄이는 게 목적입니다.

세 가지 수준에서 생각해 봅니다.

a) 즉시 추가할 수 있는 가드레일

지금 당장 현실적으로 추가할 수 있는 예방 장치는 무엇인가?

  • 입력값 검증 강화 (타입, 범위, 필수 필드 등)
  • 에러 메시지와 로그 보강 (ID, payload 구조, 환경 정보 등 포함)
  • 테스트 추가 (유닛, 통합, 이번 케이스에 대한 회귀 테스트 등)

예시:

할인 payload에 대한 스키마 검증을 추가하고, 길이 10자 초과 코드에 대한 회귀 테스트를 추가했다.

b) 중기적인 설계·아키텍처 개선

조금 더 시간을 들여 설계나 아키텍처를 개선할 수 있는 부분은?

  • 서비스 간 타입/계약을 공유 (OpenAPI, protobuf, 공유 모델 등)
  • 설정 파싱과 검증 로직을 한 곳으로 모으기
  • 더 엄격한 lint 규칙이나 타입 체크 도입

예시:

할인 payload를 세 서비스에 따로 정의하지 말고, 공통 TypeScript 타입으로 정의해 공유해야 한다.

c) 프로세스와 지식 공유

팀 차원에서 공유해야 할 것은 무엇인가?

  • 특정 서드파티 API의 특이한 동작을 팀 위키에 메모
  • 릴리스 체크리스트에 항목 추가 (“스테이징/프로덕션 env var 일치 여부 확인” 등)
  • 버그와 수정 내용을 요약한 짧은 Slack 메시지

이 단계에서 디버그 다이어리 기록이 곧 팀의 지식 베이스가 됩니다.


디버그 다이어리는 어디에 둘까?

다이어리는 가볍고, 바로 꺼내 쓸 수 있어야 합니다. 그렇지 않으면 금방 안 쓰게 됩니다.

실용적인 선택지들:

  • 레포 안에 debug-diary.md 파일 하나
  • 의미 있는 버그마다 하나씩 마크다운 파일을 두는 debug/ 폴더
  • 팀 위키 페이지나 Notion 문서
  • 개인이라면 본인이 쓰는 노트 앱

간단한 템플릿 예시는 다음과 같습니다.

# Bug: [짧은 제목] **Date:** 2025-01-01 **Environment:** (prod/staging/local, 버전 등) ## 1. 뭐가 어떻게 망가졌고, 겉으로 어떻게 드러났는가? [증상, 에러, 재현 절차] ## 2. 진짜 근본 원인은 무엇이었는가? [평이한 언어로 설명] ## 3. 어떤 데이터/설정/환경 가정이 틀렸는가? [입력, 출력, 엣지 케이스, 설정/환경 변수/외부 의존성] ## 4. 실제로 어떻게 버그를 찾았는가? [먹힌 것, 안 먹힌 것, 사용한 도구] ## 5. 이 부류의 버그를 어떻게 예방할 것인가? [가드레일, 테스트, 설계 변경, 문서화]

기록은 너무 길 필요 없습니다. 의미 있는 버그 하나당 5–10분 정도면 충분합니다.


시간이 지나면 어떤 이득이 생길까?

처음에는 일이 하나 더 늘어난 것처럼 느껴질 수 있습니다. 하지만 몇 주만 지나도 이런 변화가 보이기 시작합니다.

  • 디버깅이 빨라진다 – “이건 설정 불일치 냄새가 나는데?” 같은 패턴이 눈에 들어옵니다.
  • 반복 이슈가 줄어든다 – 아픈 데에 테스트, 검증, 로그를 이미 깔아 두었기 때문입니다.
  • 온보딩이 쉬워진다 – 새 팀원은 과거 기록을 읽으며 실제 사건에서 배울 수 있습니다.
  • 생각이 정리된다 – 증상과 원인, 추측과 사실을 구분해서 기록해야 하기 때문입니다.

같은 코드를 짜더라도, 그 옆에 작은 회고 루프 하나를 붙여 두는 셈입니다.


결론

디버깅 자체는 피할 수 없습니다. 하지만 같은 교훈을 계속해서 다시 배우는 일은 줄일 수 있습니다.

다섯 가지 질문 디버그 다이어리는 모든 버그를 작은 케이스 스터디로 바꿉니다.

  1. 뭐가 어떻게 망가졌고, 어떻게 드러났는가?
  2. 진짜 근본 원인은 무엇이었는가?
  3. 어떤 데이터/설정/환경 가정이 틀렸는가?
  4. 실제로 어떻게 버그를 찾았는가?
  5. 다음에 이 부류의 버그를 어떻게 예방할 것인가?

입력, 출력, 엣지 케이스, 설정, 환경을 꾸준히 확인하고, 실제로 어떻게 디버깅했는지까지 기록해 두면, 조용하지만 강력한 우위를 갖게 됩니다.

거창한 프로세스 변경이 필요하지 않습니다. 다음에 마주치는, 사소하지 않은 버그 하나에서 시작하면 됩니다. 마크다운 파일을 열고, 이 다섯 가지 질문에 답을 적은 뒤, 고친 코드를 배포하세요.

미래의 나와 동료들은, 그때 남겨둔 빵부스러기(단서)에 분명히 고마워할 겁니다.

다섯 가지 질문 디버그 다이어리: 모든 버그 수정을 한 단계 끌어올리는 작은 습관 | Rain Lag