[python] 파이썬에서 포착되지 않은 예외 로깅

잡히지 않는 예외가 logging아닌 모듈을 통해 어떻게 출력 stderr됩니까?

이 작업을 수행하는 가장 좋은 방법은 다음과 같습니다.

try:
    raise Exception, 'Throwing a boring exception'
except Exception, e:
    logging.exception(e)

그러나 내 상황은 예외가 포착되지 않을 때마다 자동으로 호출 되면 정말 좋을logging.exception(...)입니다.



답변

Ned가 지적했듯이 sys.excepthook예외가 발생하여 포착되지 않을 때마다 호출됩니다. 이것의 실질적인 의미는 코드에서 sys.excepthook원하는 것을 수행 하는 기본 동작을 무시할 수 있다는 것입니다 (사용 포함 logging.exception).

짚맨 예를 들면 :

>>> import sys
>>> def foo(exctype, value, tb):
...     print 'My Error Information'
...     print 'Type:', exctype
...     print 'Value:', value
...     print 'Traceback:', tb
... 

무시 sys.excepthook:

>>> sys.excepthook = foo

명백한 구문 오류를 커밋하고 (콜론 제외) 사용자 지정 오류 정보를 다시 가져옵니다.

>>> def bar(a, b)
My Error Information
Type: <type 'exceptions.SyntaxError'>
Value: invalid syntax (<stdin>, line 1)
Traceback: None

자세한 내용은 대한 sys.excepthook읽기, 워드 프로세서 .


답변

다음은 몇 가지 다른 트릭을 포함하는 완전한 작은 예입니다.

import sys
import logging
logger = logging.getLogger(__name__)
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)

def handle_exception(exc_type, exc_value, exc_traceback):
    if issubclass(exc_type, KeyboardInterrupt):
        sys.__excepthook__(exc_type, exc_value, exc_traceback)
        return

    logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))

sys.excepthook = handle_exception

if __name__ == "__main__":
    raise RuntimeError("Test unhandled")
  • Console python 프로그램이 Ctrl + C로 종료 될 수 있도록 KeyboardInterrupt를 무시하십시오.

  • 예외를 형식화하려면 파이썬의 로깅 모듈에 전적으로 의존하십시오.

  • 예제 핸들러와 함께 사용자 정의 로거를 사용하십시오. 이것은 처리되지 않은 예외를 변경하여 stderr이 아닌 stdout으로 이동하지만 동일한 스타일의 모든 종류의 핸들러를 로거 오브젝트에 추가 할 수 있습니다.


답변

sys.excepthook예외가 발생하지 않으면 메소드 가 호출됩니다. http://docs.python.org/library/sys.html#sys.excepthook

예외가 발생하여 포착되지 않으면 인터프리터는 세 개의 인수, 예외 클래스, 예외 인스턴스 및 추적 백 오브젝트와 함께 sys.excepthook을 호출합니다. 대화식 세션에서는 제어가 프롬프트로 리턴되기 직전에 발생합니다. 파이썬 프로그램에서 이것은 프로그램이 종료되기 직전에 발생합니다. 이러한 최상위 예외 처리는 sys.excepthook에 다른 3 개의 인수 함수를 할당하여 사용자 지정할 수 있습니다.


답변

왜 안되 겠어요 :

import sys
import logging
import traceback

def log_except_hook(*exc_info):
    text = "".join(traceback.format_exception(*exc_info))
    logging.error("Unhandled exception: %s", text)

sys.excepthook = log_except_hook

None()

sys.excepthook위 의 출력은 다음과 같습니다 .

$ python tb.py
ERROR:root:Unhandled exception: Traceback (most recent call last):
  File "tb.py", line 11, in <module>
    None()
TypeError: 'NoneType' object is not callable

다음은 sys.excepthook주석 처리 된 출력입니다 .

$ python tb.py
Traceback (most recent call last):
  File "tb.py", line 11, in <module>
    None()
TypeError: 'NoneType' object is not callable

유일한 차이점은 전자가 ERROR:root:Unhandled exception:첫 줄의 시작 부분에 있다는 것입니다.


답변

Jacinda의 답변을 기반으로하지만 로거 객체를 사용하려면 다음을 수행하십시오.

def catchException(logger, typ, value, traceback):
    logger.critical("My Error Information")
    logger.critical("Type: %s" % typ)
    logger.critical("Value: %s" % value)
    logger.critical("Traceback: %s" % traceback)

# Use a partially applied function
func = lambda typ, value, traceback: catchException(logger, typ, value, traceback)
sys.excepthook = func


답변

try...except잡히지 않은 예외를 모두 포착하고 기록 (및 다시 발생할 수 있음) 할 수 있도록 앱 항목 호출을 차단합니다. 예를 들어 :

if __name__ == '__main__':
    main()

이 작업을 수행:

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        logger.exception(e)
        raise


답변

어쩌면 모듈 상단에서 stderr를 파일로 리디렉션하고 하단에 해당 파일을 로깅하는 작업을 수행 할 수 있습니다

sock = open('error.log', 'w')
sys.stderr = sock

doSomething() #makes errors and they will log to error.log

logging.exception(open('error.log', 'r').read() )