Python과 JavaScript 실무 로깅 설계 가이드

Python과 JavaScript 실무 로깅 설계 가이드 관련 이미지
Photo by StockSnap via Pixabay

프로그램에 문제가 생겼을 때 가장 먼저 확인하는 것은 로그입니다. 하지만 print 문을 여기저기 추가하거나 모든 데이터를 무조건 기록하면 원인을 찾기는커녕 중요한 신호가 잡음 속에 묻힐 수 있습니다. 실무 로깅은 단순한 문자열 출력이 아니라 요청의 흐름과 실패 원인, 성능 변화를 추적할 수 있는 관찰 가능성의 기반입니다. Python과 JavaScript 프로젝트에서 재사용할 수 있는 로깅 원칙과 오류 대응 방법을 정리합니다.

로그 레벨을 목적에 맞게 구분하기

DEBUG는 개발 과정에서 변수와 상세 흐름을 확인할 때, INFO는 서비스의 정상적인 주요 이벤트를 기록할 때 사용합니다. WARNING은 현재 요청은 처리됐지만 주의가 필요한 상태, ERROR는 기능이 실패했으나 프로세스는 계속 실행되는 상태, CRITICAL은 서비스 지속이 어려운 심각한 상황에 적합합니다. 정상적인 사용자 입력 오류를 모두 ERROR로 남기면 실제 장애를 구분하기 어려워집니다. 팀이 각 레벨의 기준을 문서로 합의하는 것이 중요합니다.

문자열보다 구조화된 로그 사용하기

‘주문 실패’라는 문장만 남기면 어떤 사용자, 어떤 주문, 어떤 단계에서 실패했는지 알 수 없습니다. JSON 형태의 구조화된 로그에 event, request_id, order_id, duration_ms, status 같은 필드를 넣으면 검색과 집계가 쉬워집니다. Python에서는 logging 설정에 JSON 포매터를 연결할 수 있고, JavaScript에서는 Pino나 Winston 같은 로깅 도구를 활용할 수 있습니다. 필드 이름은 서비스마다 다르게 만들지 말고 공통 규칙을 정해야 대시보드와 알림을 재사용할 수 있습니다.

요청 ID로 전체 흐름 연결하기

하나의 웹 요청이 API 서버, 작업 큐, 데이터베이스와 외부 결제 서비스를 지나간다면 같은 request_id 또는 trace_id를 전달해야 합니다. 사용자가 오류를 신고했을 때 이 ID 하나로 관련 로그를 시간순으로 모을 수 있습니다. 비동기 작업을 큐에 넣을 때도 원래 요청 ID와 별도의 job_id를 함께 기록하면 누가 어떤 작업을 시작했는지 추적하기 쉽습니다.

절대 로그에 남기면 안 되는 정보

  • 비밀번호와 애플리케이션 비밀번호
  • API 키, 액세스 토큰과 세션 쿠키
  • 주민등록번호, 카드번호와 계좌정보
  • 사용자의 전체 이메일·전화번호·주소
  • 인증 헤더와 원문 요청 본문

필요한 경우 개인정보는 일부를 마스킹하고 토큰은 존재 여부나 끝 몇 자리만 기록합니다. 예외 객체나 HTTP 요청 전체를 자동 직렬화하면 헤더에 포함된 인증정보가 노출될 수 있으므로 로깅 라이브러리의 필드 제거 기능을 설정해야 합니다. 운영 로그는 여러 사람이 접근하고 장기간 보관될 수 있다는 전제로 설계하는 편이 안전합니다.

Python 오류 로깅 실전 패턴

Python에서는 logger.exception을 예외 처리 블록 안에서 사용하면 메시지와 스택 트레이스를 함께 기록할 수 있습니다. 단, 같은 예외를 하위 함수와 상위 함수에서 반복 기록하면 하나의 장애가 여러 건처럼 보일 수 있습니다. 예외를 실제로 처리하는 경계에서 한 번만 충분한 문맥과 함께 기록하세요. 재시도할 오류라면 attempt, max_attempts와 다음 대기 시간을 필드로 남기는 것이 좋습니다.

JavaScript 비동기 오류 추적하기

JavaScript의 Promise를 await하지 않거나 catch 없이 실행하면 처리되지 않은 거부가 발생할 수 있습니다. 비동기 함수의 오류는 호출 경로에서 명시적으로 처리하고, 사용자에게 반환할 안전한 메시지와 내부 조사에 필요한 상세 로그를 분리해야 합니다. 브라우저에서는 소스맵을 보관해 압축된 코드의 오류 위치를 원래 소스로 되돌릴 수 있어야 하며, 서버에서는 프로세스 수준의 예외를 기록한 뒤 안전하게 종료하고 재시작하는 정책이 필요합니다.

성능 로그와 메트릭 연결하기

모든 요청의 시작과 종료를 장문의 로그로 남기는 대신 처리 시간, 상태 코드, 오류 유형은 메트릭으로 집계하는 편이 효율적입니다. 로그는 개별 사건의 문맥을 설명하고 메트릭은 전체 추세를 보여 줍니다. 평균 응답 시간뿐 아니라 p95와 p99 지연 시간, 오류율, 외부 API 실패율, 작업 큐 대기 시간을 함께 확인하세요. 특정 임계값을 넘었을 때만 상세 로그를 남기거나 샘플링을 적용하면 저장 비용을 줄일 수 있습니다.

로깅 코드 테스트와 협업 규칙

  1. 오류 발생 시 필요한 이벤트와 식별자가 기록되는지 테스트합니다.
  2. 비밀번호와 토큰이 마스킹되는지 자동 테스트를 추가합니다.
  3. 로그 스키마 변경은 코드 변경처럼 리뷰합니다.
  4. 알림에는 해결 행동과 담당 팀 정보를 포함합니다.
  5. 보관 기간과 접근 권한을 환경별로 구분합니다.

Pull Request에서는 새 기능이 어떤 성공·실패 로그와 메트릭을 제공하는지 확인하는 것이 좋습니다. 로그 문장만 보고 판단하지 말고 실제 장애 상황을 가정해 검색 가능한 필드가 충분한지 검토하세요. 개발 환경에서는 상세 로그를 사용할 수 있지만 운영 환경에서는 레벨과 샘플링, 보관 비용을 조정해야 합니다.

한 줄 요약: 좋은 실무 로그는 많이 출력하는 로그가 아니라 구조화된 필드와 요청 ID로 흐름을 연결하고 민감정보를 제거하며 메트릭·테스트·팀 규칙과 함께 운영하는 로그입니다.