복붙노트

[PYTHON] 파이썬에서 캐치되지 않은 예외를 로깅하기

PYTHON

파이썬에서 캐치되지 않은 예외를 로깅하기

캐치되지 않은 예외를 stderr 대신 로깅 모듈을 통해 출력하도록하려면 어떻게해야합니까?

이 일을하는 가장 좋은 방법은 다음과 같을 것입니다.

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

그러나 예외 상황이 잡히지 않을 때마다 logging.exception (...)이 자동으로 호출되는 경우 상황이 정말 좋을 것입니다.

해결법

  1. ==============================

    1.Ned가 지적했듯이 sys.excepthook은 예외가 발생하고 캐치되지 않을 때마다 호출됩니다. 실용적인 의미는 sys.excepthook의 기본 동작을 재정의하여 원하는대로 수행 할 수 있다는 것입니다 (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에 대한 자세한 내용은 다음을 참조하십시오. http://docs.python.org/library/sys.html#sys.excepthook

  2. ==============================

    2.다음은 몇 가지 다른 트릭을 포함하는 작은 예제입니다.

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

    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")
    
  3. ==============================

    3.예외가 catch되지 않으면 sys.excepthook 메서드가 호출됩니다. http://docs.python.org/library/sys.html#sys.excepthook

    예외가 catch되지 않으면 sys.excepthook 메서드가 호출됩니다. http://docs.python.org/library/sys.html#sys.excepthook

  4. ==============================

    4.왜 안돼 :

    왜 안돼 :

    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 : 처리되지 않은 예외 : 첫 번째 줄의 시작 부분에.

  5. ==============================

    5.Jacinda의 대답을 기반으로하지만 로거 객체 사용 :

    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
    
  6. ==============================

    6.try ... except 블록에서 응용 프로그램 항목 호출을 감싸서 잡히지 않은 모든 예외를 잡아서 기록하고 다시 올릴 수 있습니다. 예 : 대신에:

    try ... except 블록에서 응용 프로그램 항목 호출을 감싸서 잡히지 않은 모든 예외를 잡아서 기록하고 다시 올릴 수 있습니다. 예 : 대신에:

    if __name__ == '__main__':
        main()
    

    이 작업을 수행:

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

    7.어쩌면 stderr을 파일로 리디렉션 한 모듈의 맨 위에서 뭔가를 할 수 있고 그 파일을 맨 아래에 logg로 만들 수 있습니다.

    어쩌면 stderr을 파일로 리디렉션 한 모듈의 맨 위에서 뭔가를 할 수 있고 그 파일을 맨 아래에 logg로 만들 수 있습니다.

    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() )
    
  8. ==============================

    8.@ gnu_lorien의 대답이 나에게 좋은 출발점을 주었지만, 첫 번째 예외는 내 프로그램이 충돌합니다.

    @ 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()
    
  9. from https://stackoverflow.com/questions/6234405/logging-uncaught-exceptions-in-python by cc-by-sa and MIT license