source

Python에서 수집되지 않은 예외 기록

factcode 2022. 11. 5. 08:56
반응형

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_infosys.excepthook3월 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

반응형