"Sentry가 보여준 진실"
11년차 QA 엔지니어로서 수많은 버그 리포트를 작성하고, 개발자들에게 "이런 에러가 발생합니다"라고 전달해왔습니다. 그런데 막상 제가 개발자가 되어보니, 그 에러들이 어디서 어떻게 발생하는지 추적하는 것이 얼마나 어려운 일인지 깨닫게 되었죠.
특히 "가끔 발생한다"거나 "특정 조건에서만 재현된다"는 이슈들... QA 시절엔 그저 리포트만 작성했지만, 이제는 제가 그 원인을 찾아야 하는 입장이 되었습니다.
처음엔 console.log만으로도 충분할 거라 생각했습니다. 로컬에서는 브라우저 콘솔을 열면 되고, 백엔드는 터미널에서 로그를 보면 되니까요. 하지만 Vercel에 배포하고 나서 문제가 시작되었습니다.
"어? 결제가 안 된다는데... 로그를 어떻게 보지?"
"프론트엔드에서 에러가 났다는데, 사용자 브라우저 콘솔을 볼 수는 없잖아..."
"백엔드 로그는 Vercel Functions 로그에서 봐야 하는데, 이게 또 찾기가..."
"어? 결제가 안 된다는데... 로그를 어떻게 보지?" "프론트엔드에서 에러가 났다는데, 사용자 브라우저 콘솔을 볼 수는 없잖아..." "백엔드 로그는 Vercel Functions 로그에서 봐야 하는데, 이게 또 찾기가..."
특히 결정적이었던 건, 한 사용자가 "가입이 안 돼요"라고 문의했을 때였습니다. 로컬에서는 잘 되는데, 운영에서만 안 된다... QA 시절이었다면 "운영 환경에서만 발생하는 이슈"라고 리포트했겠지만, 이제는 제가 원인을 찾아야 했죠.
처음엔 하나의 Sentry 프로젝트에 모든 환경을 넣으려고 했습니다. 하지만 곧 문제를 깨달았죠.
"개발 환경의 테스트 에러와 운영 환경의 실제 에러가 섞여있네?"
"이거 구분이 안 되는데..."
"개발 환경의 테스트 에러와 운영 환경의 실제 에러가 섞여있네?" "이거 구분이 안 되는데..."
결국 환경별로 Sentry 프로젝트를 분리하기로 했습니다.
jamescompany-frontend-local
jamescompany-frontend-dev
jamescompany-frontend-prod
jamescompany-backend-local
jamescompany-backend-dev
jamescompany-backend-prod
먼저 프론트엔드부터 시작했습니다.
처음엔 tracesSampleRate를 모든 환경에서 1.0으로 설정했다가, 운영 환경에서 Sentry 할당량이 순식간에 차버리는 걸 경험했습니다. "아... 이래서 샘플링을 하는구나."
백엔드는 FastAPI와의 통합이 필요했습니다.
https://gist.github.com/jamescompany/06bbc7c3e8b506aea5242e4e997203c5
특히 before_send_filter는 정말 중요했습니다. 처음엔 이걸 설정 안 했다가, Sentry 대시보드에 사용자 비밀번호가 그대로 노출되는 것을 보고 식은땀이 났죠...
단순히 에러만 기록하는 게 아니라, 에러가 발생한 상황을 함께 기록하는 것이 중요했습니다.
에러 추적만큼 중요했던 게 사용자 행동 분석이었습니다. QA 시절엔 "이 기능을 사용자가 쓸까요?"라는 질문을 많이 했는데, 이제는 직접 데이터로 확인할 수 있게 되었죠.
처음엔 모든 클릭을 추적하려고 했다가, GA 할당량 문제와 함께 "정작 중요한 데이터를 찾기 어렵다"는 걸 깨달았습니다. 핵심 행동만 추적하는 게 중요하더라고요.
이렇게 구조화된 로깅을 하니, 운영 환경에서 특정 요청의 전체 흐름을 추적하기가 훨씬 쉬워졌습니다.
모니터링을 제대로 구축하고 나서 발견한 문제들이 정말 많았습니다.
"어? 메모리 사용량이 계속 올라가네?"
Sentry 성능 모니터링에서 발견한 첫 번째 문제였습니다. 알고보니 파일 업로드 처리에서 메모리를 제대로 해제하지 않고 있었죠.
Sentry의 성능 추적에서 하나의 API 호출에 100개 이상의 DB 쿼리가 발생하는 걸 발견했습니다.
가장 충격적이었던 건, 개발 환경과 운영 환경의 미묘한 차이로 인한 에러들이었습니다.
Sentry Error: "CORS policy: No 'Access-Control-Allow-Origin' header"
- 환경: Production
- 빈도: 487회/일
- 원인: 운영 환경 CORS 설정 누락
모든 에러가 같은 무게를 가지지 않습니다.
Critical: 결제 실패, 로그인 불가
High: 주요 기능 오류
Medium: UI 깨짐, 부가 기능 오류
Low: 콘솔 경고, 성능 저하
"느려도 되는 거 아니에요?"라고 생각했던 API가 실제로는 사용자 이탈의 주요 원인이었습니다.
3초 이상 걸리는 API → 50% 이탈
5초 이상 → 90% 이탈
Local: 상세한 디버그 로그 + 콘솔 출력
Development: Sentry 전체 추적 + GA 이벤트 테스트
Production: 핵심 에러만 + 성능 샘플링 + 실제 사용자 행동 분석
QA 엔지니어로서 "재현 불가" 이슈를 리포트할 때마다 개발자들이 답답해하는 모습을 많이 봤습니다. 이제 그 답답함을 직접 경험하면서, 왜 모니터링이 중요한지 뼈저리게 느끼고 있죠.
특히 Sentry가 보여준 진실은 충격적이었습니다.
내가 "완벽하다"고 생각한 코드의 에러들
로컬에서는 절대 발견할 수 없었던 운영 환경 이슈
사용자들이 겪고 있었지만 리포트하지 않은 수많은 문제들
이제는 QA를 할 때도 다르게 접근합니다.
"이 에러는 모니터링에서 잡힐까?"
"개발자가 이 이슈를 추적할 수 있을까?"
"재현 경로뿐만 아니라 컨텍스트 정보도 충분히 제공했나?"
"측정할 수 없으면 개선할 수 없다" - 이 말의 의미를 이제야 제대로 이해하게 되었습니다.
다음 편에서는 제가 QA 엔지니어로서 직접 만든 QA 플랫폼의 핵심 기능들에 대해 이야기해보겠습니다. Coffee-Chat부터 Bug Bounty Arena까지, QA 엔지니어들을 위한 QA 도구들의 개발기를 공유하겠습니다.