Python에서 수집되지 않은 예외 기록
수집되지 않은 예외는 어떻게 하면logging
모듈화하지 않고stderr
?
이를 위한 최선의 방법은 다음과 같습니다.
try:
raise Exception, 'Throwing a boring exception'
except Exception, e:
logging.exception(e)
하지만 제 상황이 너무 심각해서logging.exception(...)
예외가 검출되지 않을 때마다 자동으로 호출됩니다.
다음은 기타 몇 가지 요령을 포함한 간단한 예입니다.
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")
키보드 무시콘솔 python 프로그램이 Ctrl + C로 종료되도록 인터럽트합니다.
예외 포맷은 python의 로깅 모듈에 전적으로 의존합니다.
사용자 지정 로거를 예제 핸들러와 함께 사용합니다.이것은 처리되지 않은 예외를 stderr이 아닌 stdout으로 이동하도록 변경하지만 이 스타일의 모든 종류의 핸들러를 로거 오브젝트에 추가할 수 있습니다.
네드가 지적했듯이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
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:
첫 번째 줄의 선두에.
방법sys.excepthook
예외가 검출되지 않은 경우 호출됩니다.http://docs.python.org/library/sys.html#sys.excepthook
예외가 발생하여 수집되지 않은 경우 인터프리터는 예외 클래스, 예외 인스턴스 및 트레이스백개체의 3가지 인수를 사용하여 sys.excepthook을 호출합니다.대화형 세션에서는 제어가 프롬프트로 반환되기 직전에 발생합니다.Python 프로그램에서는 프로그램이 종료되기 직전에 발생합니다.이러한 최상위 예외 처리는 sys.excepthook에 다른 3개의 인수 함수를 할당하여 맞춤화할 수 있습니다.
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
내 경우 (사용)python 3
@Jacinda의 답변을 사용할 때 트레이스백의 내용은 인쇄되지 않았습니다.대신 오브젝트 자체를 인쇄합니다.<traceback object at 0x7f90299b7b90>
.
대신, 나는:
import sys
import logging
import traceback
def custom_excepthook(exc_type, exc_value, exc_traceback):
# Do not print exception when user cancels the program
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logging.error("An uncaught exception occurred:")
logging.error("Type: %s", exc_type)
logging.error("Value: %s", exc_value)
if exc_traceback:
format_exception = traceback.format_tb(exc_traceback)
for line in format_exception:
logging.error(repr(line))
sys.excepthook = custom_excepthook
을 앱 a a a a a wrap wrap wrap 。try...except
과 같이 입력합니다.
if __name__ == '__main__':
main()
다음을 수행합니다.
if __name__ == '__main__':
try:
main()
except Exception as e:
logger.exception(e)
raise
@gnu_lorien의 답변은 좋은 출발점이 되었지만, 첫 번째 예외로 프로그램이 크래시 됩니다.
'을 '을 '예외기능'으로 로 남기는 했습니다.이 솔루션은 다음과 같이 장식된 기능의 예외를 자동으로 기록합니다.@handle_error
.
import logging
__author__ = 'ahmed'
logging.basicConfig(filename='error.log', level=logging.DEBUG)
def handle_exception(exc_type, exc_value, exc_traceback):
import sys
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logging.critical(exc_value.message, exc_info=(exc_type, exc_value, exc_traceback))
def handle_error(func):
import sys
def __inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception, e:
exc_type, exc_value, exc_tb = sys.exc_info()
handle_exception(exc_type, exc_value, exc_tb)
finally:
print(e.message)
return __inner
@handle_error
def main():
raise RuntimeError("RuntimeError")
if __name__ == "__main__":
for _ in xrange(1, 20):
main()
모듈 상단에서 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() )
승인된 답변의 코멘트 섹션에서 논의된 Zeus 씨의 질문에 답하기 위해, 저는 이를 사용하여 PyCharm 2018-2019에서 테스트된 대화형 콘솔에 수집되지 않은 예외를 기록합니다.는 아아를 알았다.sys.excepthook
하지 않기 Python을 사용할 수 .sys.exc_info
however. 단, 지만,,,sys.exc_info
가 sys.excepthook
3월 1일, 3번으로 하다
에서는 ㄹ게요, ㄹ게요, ㄹ게요.sys.excepthook
★★★★★★★★★★★★★★★★★」sys.exc_info
대화형 콘솔과 래퍼 기능이 있는 스크립트에 두 예외를 모두 기록합니다.두 함수에 후크 함수를 연결하려면 인수 지정 여부에 따라 2개의 인터페이스가 있습니다.
코드는 다음과 같습니다.
def log_exception(exctype, value, traceback):
logger.error("Uncaught exception occurred!",
exc_info=(exctype, value, traceback))
def attach_hook(hook_func, run_func):
def inner(*args, **kwargs):
if not (args or kwargs):
# This condition is for sys.exc_info
local_args = run_func()
hook_func(*local_args)
else:
# This condition is for sys.excepthook
hook_func(*args, **kwargs)
return run_func(*args, **kwargs)
return inner
sys.exc_info = attach_hook(log_exception, sys.exc_info)
sys.excepthook = attach_hook(log_exception, sys.excepthook)
로깅 설정은 gnu_lorien의 답변에서 찾을 수 있습니다.
언급URL : https://stackoverflow.com/questions/6234405/logging-uncaught-exceptions-in-python
'source' 카테고리의 다른 글
일주일보다 새로운 행을 선택하려면 어떻게 해야 합니까? (0) | 2022.11.05 |
---|---|
Linux와 Windows 모두에서 Python에서 "/"(디렉토리 구분자)를 사용하는 방법은 무엇입니까? (0) | 2022.11.05 |
일일 수익 점유율을 기준으로 고정 값을 국가에 분할할 때 특정 값 제외 (0) | 2022.11.05 |
오래된 Mac OS의 C 컴파일러에서 \n의 값은 얼마입니까? (0) | 2022.11.05 |
MacRoman, CP1252, Latin1, UTF-8 및 ASC 사이의 부호화를 확실하게 추측하는 방법II (0) | 2022.11.05 |