파이썬 로그에 traceback이 안 남을 때 logging.exception과 exc_info 선택법

파이썬 자동화에서 예외 메시지만 기록되고 traceback이 남지 않는다면, 예외를 처리하는 except 블록에서는 logging.exception() 또는 exc_info=True를 먼저 검토하면 됩니다. stack_info=True는 예외의 호출 경로가 아니라 현재 logging 호출 지점까지의 스택을 남길 때 사용하며, traceback.print_exc()는 logging 레코드를 만들지 않습니다. 따라서 어떤 API를 고를지와 함께 logger·handler의 레벨 및 출력 대상을 확인해야 합니다.

예외 traceback을 로그에 남기는 기본 선택

운영 중인 배치나 예약 작업이 실패했을 때 메시지만 남으면 “무엇이 잘못됐는가”는 알 수 있어도 “어느 호출 경로에서 실패했는가”를 좁히기 어렵습니다. 저라면 먼저 예외가 실제로 발생한 except 블록을 찾고, 그 안에서 logging 레코드를 만들도록 정리합니다.

import logging

logger = logging.getLogger(__name__)

try:
    run_automation()
except Exception:
    logger.exception("자동화 작업 실패")

Logger.exception()은 error 수준의 로그를 남기면서 현재 처리 중인 예외 정보를 함께 기록하는 API입니다. 예외 처리기 안에서 호출하는 형태가 의도에 맞습니다. 메시지는 작업 이름처럼 사람이 빠르게 알아볼 수 있는 내용으로 두고, 예외 객체의 상세 traceback은 logging이 붙이도록 맡기는 편이 관리하기 쉽습니다.

logging.exception과 exc_info=True의 차이

두 방식 모두 except 블록에서 현재 예외 정보를 로그에 포함할 수 있습니다. 차이는 주로 표현 방식과 로그 수준을 함께 지정하는 유연성에 있습니다.

try:
    run_automation()
except Exception:
    logger.error("자동화 작업 실패", exc_info=True)

exc_info=True는 현재 예외 정보를 로그 레코드에 추가합니다. 이미 warning이나 critical 같은 다른 레벨을 사용해야 하거나, 공통 로깅 함수에서 레벨을 매개변수로 받는 구조라면 이 형태가 자연스럽습니다. 특별한 이유 없이 두 호출을 연달아 쓰면 같은 실패에 대한 traceback이 중복될 수 있으므로 한 경로에서 하나를 선택합니다.

간단히 정리하면 다음과 같습니다.

  • except 블록에서 실패를 error 로그로 남기는 일반적인 경우: logger.exception("...")
  • 로그 레벨을 별도로 정하거나 공통 함수에서 제어해야 하는 경우: logger.error("...", exc_info=True)
  • 예외가 없는 현재 호출 경로를 확인하려는 경우: stack_info=True

stack_info=True는 다른 문제를 보여줍니다

stack_info는 예외를 되감아 추적하는 정보가 아니라 logging 호출 지점까지의 현재 스택을 덧붙입니다. 따라서 예외가 없어도 독립적으로 사용할 수 있습니다.

logger.debug("작업 분기 진입", stack_info=True)

예외가 이미 발생한 상황에서 실패 원인을 확인하려면 exc_info 계열이 우선입니다. 반대로 예외는 없지만 특정 함수가 어떤 호출 경로에서 자주 진입하는지 확인하려면 stack_info=True가 맞습니다. 두 정보가 모두 필요한 진단 구간에서는 함께 사용할 수 있지만, 운영 로그의 양과 민감정보 포함 가능성을 먼저 검토해야 합니다.

traceback.print_exc()를 무작정 추가하지 않는 이유

traceback.print_exc()는 현재 처리 중인 예외의 traceback을 출력하지만 logging 레코드를 만들지는 않습니다. 기본 출력 경로와 logging handler가 관리하는 파일 경로가 다를 수 있기 때문에, 콘솔에서는 보이는데 파일 로그에는 없는 상황이 생길 수 있습니다.

try:
    run_automation()
except Exception:
    logger.exception("자동화 작업 실패")

파일·콘솔·수집 시스템이 logging으로 연결된 애플리케이션이라면, 예외 traceback도 같은 logging 경로로 보내는 편이 추적 기준을 하나로 유지하기 쉽습니다. traceback.print_exception()이 특정 파일 객체에 직접 출력해야 하는 별도 요구가 있을 때만 출력 대상을 명확히 정해 사용합니다.

traceback이 여전히 파일에 없을 때 점검 순서

호출을 바꿨는데도 파일 로그에 보이지 않는다면 코드 한 줄만의 문제가 아닐 수 있습니다.

  1. except 블록이 실제로 실행되는지 확인합니다.
  2. logger가 해당 error 이벤트를 허용하는 레벨인지 확인합니다.
  3. 목적지 handler의 레벨이 더 높게 설정되어 이벤트를 걸러내지 않는지 확인합니다.
  4. 파일 출력이 필요하다면 FileHandler가 실제 목적지로 등록되어 있는지 확인합니다.
  5. 상위 logger의 handler로 전달되는 구조에서 중복 출력이나 다른 목적지 누락이 없는지 확인합니다.
  6. traceback에 예외 메시지나 입력값이 포함될 수 있으므로 운영 로그에 남겨도 되는 정보인지 점검합니다.

로거 레벨은 처리할 최소 심각도를 정하고, handler 레벨은 해당 목적지로 보낼 최소 심각도를 정합니다. FileHandler는 로그 레코드를 디스크 파일로 보내지만, 두 레벨과 handler 등록이 맞지 않으면 올바른 exception() 호출도 기대한 파일에 나타나지 않습니다. 로그 파일 자체가 생성되지 않는다면 파이썬 로그 파일이 안 생기는 이유와 logging 설정 점검법을 먼저 확인하는 순서가 맞습니다.

운영에 적용하기 전 마지막 판단

예외 처리 중 traceback을 남기는 목적이면 logging.exception()을 기본값으로 두고, 로그 레벨을 호출부에서 제어해야 할 때 exc_info=True를 선택하면 됩니다. 예외가 없는 호출 경로를 조사하는 목적이면 stack_info=True를 별도로 판단하고, traceback.print_exc()는 logging 기반 수집 경로와 분리된 출력이라는 점을 기억해야 합니다.

다음으로는 예외 로그에 작업 ID나 요청값을 함께 넣을 때 민감정보를 어떻게 제외할지, 예약 실행 환경에서 실제 파일 handler까지 같은 로그가 도달하는지를 확인하면 됩니다.

출처

Leave a Comment