서비스 운영 ·
오류와 로그를 진료 기록처럼 읽고 원인을 좁히는 순서
먼저 답부터
디버깅은 오류 문장을 지우는 일이 아니라 같은 문제를 다시 만들 수 있는 조건을 기록하고 첫 실패 지점을 찾는 과정입니다. 화면 증상, 입력, 시간, 파일과 줄 번호, 기대 결과를 분리해 적은 뒤 한 번에 한 가지만 바꾸면 로그의 결과와 실제 원인을 혼동할 가능성이 줄어듭니다.
버튼을 눌러도 반응이 없을 때 AI에게 ‘고쳐 줘’라고만 하면 관련 없는 파일까지 바뀌기 쉽습니다. 화면에서 보이는 증상과 실제 오류가 난 위치는 다를 수 있기 때문입니다. 먼저 무엇을 했을 때 무엇을 기대했고 실제로 무엇이 달랐는지 기록해야 합니다.
디버깅은 프로그램 문제의 원인을 체계적으로 좁히는 과정입니다. 로그는 프로그램이 실행되며 남긴 사건 기록이고, 오류 메시지는 실패 종류와 위치를 알려 주는 단서입니다. 병원에서 아프다는 말만 듣지 않고 증상이 시작된 시간과 검사 결과를 함께 보는 것처럼 세 정보를 연결해야 합니다.
증상과 원인은 같은 말이 아니다
‘저장 버튼이 안 된다’는 증상입니다. 원인은 입력 검증 실패, 네트워크 끊김, 서버 권한 거절, JavaScript 예외 등 여러 가지일 수 있습니다. 처음부터 원인을 단정하면 다른 단서를 무시하게 됩니다.
기대 결과도 구체적으로 적습니다. ‘정상 작동’보다 ‘버튼을 한 번 누르면 성공 문구가 보이고 목록 맨 위에 새 항목이 나타나야 한다’가 낫습니다. 실제 결과에는 화면 문구, 상태 코드, 발생 시각을 적되 비밀번호나 토큰 같은 값은 제외합니다.
콘솔은 브라우저가 남긴 실행 기록을 보여 준다
Chrome DevTools의 Console은 기록된 메시지를 보고 JavaScript를 시험하는 도구입니다. 빨간 줄이라고 모두 같은 문제는 아닙니다. 광고 차단 확장 프로그램의 경고, 오래된 라이브러리 안내, 내 코드의 예외가 함께 보일 수 있습니다.
TypeError: Cannot read properties of undefined
at showProfile (profile.js:18:12)
이 예시에서 ‘TypeError’는 값의 종류나 사용 방식이 맞지 않을 때 나타나는 오류 이름이고, 뒤 문장은 정의되지 않은 값에서 속성을 읽으려 했다는 단서입니다. ‘profile.js:18:12’는 파일, 줄, 칸 위치입니다. MDN 오류 참고 문서는 오류 이름과 메시지를 문제 이해의 출발점으로 사용할 수 있다고 설명합니다.
스택은 실패가 지나온 호출 경로다
스택 트레이스는 함수가 어떤 순서로 불리다가 실패했는지 보여 주는 목록입니다. 배달 추적에서 물건이 어느 터미널을 거쳤는지 보는 기록과 비슷합니다. 맨 위가 직접 실패한 위치인 경우가 많지만, 잘못된 값은 더 앞 단계에서 만들어졌을 수 있습니다.
내가 작성한 파일과 외부 패키지 파일을 구분하고, 가장 먼저 내 코드로 연결되는 줄을 엽니다. 압축된 공개 코드만 보고 고치기 어렵다면 로컬 개발 환경에서 같은 조건을 재현합니다. 스택 전체를 AI에 붙일 때는 주소, 사용자 식별자, 요청 헤더가 포함됐는지 먼저 가립니다.
재현 절차는 문제를 다시 만드는 짧은 조리법이다
재현은 같은 입력과 순서로 같은 문제가 다시 나타나게 하는 일입니다. 계정, 브라우저, 화면 너비, 입력값, 클릭 순서를 기록합니다. ‘가끔’이라는 표현 대신 세 번 중 몇 번 발생했는지 실제 관찰만 적습니다.
한 번에 여러 코드를 바꾸면 어느 변경이 효과가 있었는지 알 수 없습니다. 먼저 가장 작은 재현을 만들고 한 가지만 바꿉니다. 예를 들어 빈 이름에서만 저장이 실패한다면 디자인 전체를 바꾸지 않고 입력 검증과 서버 응답부터 봅니다.
로그는 필요한 맥락만 남겨야 한다
좋은 로그는 시각, 작업 종류, 결과, 오류 식별자를 남깁니다. 나쁜 로그는 비밀번호, API 키, 전체 결제 정보, 주민등록번호 같은 민감정보를 그대로 출력합니다. 운영 로그는 개발자 도구가 아니라 실제 사용자 데이터가 쌓일 수 있는 기록이라는 점을 기억해야 합니다.
- 비밀키와 인증 헤더는 절대 로그에 남기지 않습니다.
- 이메일과 사용자 ID는 꼭 필요한지 검토하고 최소화합니다.
- 성공과 실패를 같은 작업 이름으로 연결합니다.
- 오류를 삼키지 말고 사용자에게 안전한 다음 행동을 보여 줍니다.
- 로그 보관 기간과 접근 권한을 정합니다.
- 수정 뒤 같은 재현 절차로 문제가 사라졌는지 확인합니다.
첫 실패부터 좁히는 점검 순서
화면에서 마지막으로 성공한 단계와 처음 실패한 단계를 나눕니다. 버튼 클릭 이벤트가 기록됐다면 클릭 연결은 통과했고, 네트워크 요청이 없다면 요청을 만드는 코드 사이를 봅니다. 요청은 갔지만 401이 왔다면 화면 색보다 인증 상태를 먼저 확인합니다.
오류가 여러 개 보이면 가장 처음 발생한 오류부터 봅니다. 첫 실패 때문에 뒤에서 연쇄 오류가 생길 수 있습니다. 새로고침 후 필터를 비우고 같은 동작을 한 번만 재현하면 오래된 메시지와 현재 메시지를 구분하기 쉽습니다.
오늘 바로 해볼 작은 실습
개인정보가 없는 연습 페이지에서 개발자 도구를 열고 기록만 합니다.
- 기대 행동을 한 문장으로 적습니다.
- Console을 비운 뒤 버튼이나 링크를 한 번만 실행합니다.
- 첫 오류의 이름, 메시지, 파일과 줄 번호를 적습니다.
- 같은 순서를 다시 해 같은 오류가 나는지 확인합니다.
- 입력 하나만 바꿔 발생 조건이 달라지는지 봅니다.
- 수정 전후 결과를 같은 문장 형식으로 기록합니다.
운영 사이트 콘솔에 출처를 모르는 코드를 붙여 넣지 마세요. 로그를 얻기 위해 실제 결제, 삭제, 이메일 발송을 반복하지 않고 테스트 환경과 가짜 데이터를 사용합니다. 오류 문장을 가리려고 경고를 끄거나 try-catch로 전부 삼키지 않습니다. 증상, 재현, 첫 실패, 한 가지 변경 순서를 지키면 코드를 다 알지 못해도 AI에게 훨씬 정확한 진단 자료를 줄 수 있습니다.
확인한 자료
- Console overview — Chrome for Developers
- JavaScript error reference — MDN Web Docs