디버그 정보로 Python 오류를 어떻게 기록합니까?
다음을 사용하여 Python 예외 메시지를 로그 파일에 인쇄하고 있습니다 logging.error
.
import logging
try:
1/0
except ZeroDivisionError as e:
logging.error(e) # ERROR:root:division by zero
예외 문자열보다 예외 및 예외를 생성 한 코드에 대한 자세한 정보를 인쇄 할 수 있습니까? 줄 번호 또는 스택 추적과 같은 것이 좋습니다.
logger.exception
오류 메시지와 함께 스택 추적을 출력합니다.
예를 들면 다음과 같습니다.
import logging
try:
1/0
except ZeroDivisionError as e:
logging.exception("message")
산출:
ERROR:root:message
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
@Paulo Check 메모, "Python 3 logging.exception
에서는 except
파트 내부 에서 메소드 를 호출해야합니다 . 임의의 위치에서이 메소드를 호출하면 기괴한 예외가 발생할 수 있습니다. 문서는 이에 대해 경고합니다."
에 대한 하나의 좋은 일이 logging.exception
있음을 SiggyF의 대답은 표시되지 않습니다 당신이 임의의 메시지를 전달할 수 있으며, 기록은 여전히 예외 세부 사항 전체 역 추적을 보여줄 것입니다 :
import logging
try:
1/0
except ZeroDivisionError:
logging.exception("Deliberate divide by zero traceback")
에 오류를 인쇄하는 기본 (최신 버전) 로깅 동작을 사용 sys.stderr
하면 다음과 같습니다.
>>> import logging
>>> try:
... 1/0
... except ZeroDivisionError:
... logging.exception("Deliberate divide by zero traceback")
...
ERROR:root:Deliberate divide by zero traceback
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
오류 수준을 선택할 수 있도록 exc_info 옵션을 사용하는 것이 좋습니다 (을 사용 exception
하는 경우 항상 표시됨 error
).
try:
# do something here
except Exception as e:
logging.fatal(e, exc_info=True) # log exception info at FATAL log level
logging
모듈을 사용하지 않고 애플리케이션이 다른 방식으로 로깅하는 경우 어떻게 합니까?
이제 traceback
여기서 사용할 수 있습니다.
import traceback
def log_traceback(ex, ex_traceback=None):
if ex_traceback is None:
ex_traceback = ex.__traceback__
tb_lines = [ line.rstrip('\n') for line in
traceback.format_exception(ex.__class__, ex, ex_traceback)]
exception_logger.log(tb_lines)
파이썬 2 에서 사용하십시오 :
try: # your function call is here except Exception as ex: _, _, ex_traceback = sys.exc_info() log_traceback(ex, ex_traceback)
파이썬 3 에서 사용하십시오 :
try: x = get_number() except Exception as ex: log_traceback(ex)
일반 로그를 사용하는 경우 모든 로그 레코드는이 규칙과 일치해야합니다 one record = one line
. 이 규칙에 따라 grep
및 기타 도구를 사용 하여 로그 파일을 처리 할 수 있습니다.
그러나 역 추적 정보는 여러 줄입니다. 그래서 내 대답은 이 스레드에서 위의 zangw가 제안한 확장 버전의 솔루션 입니다. 문제는 역 추적 라인이 \n
내부에 있을 수 있으므로이 라인 엔딩을 제거하기 위해 추가 작업을 수행해야한다는 것입니다.
import logging
logger = logging.getLogger('your_logger_here')
def log_app_error(e: BaseException, level=logging.ERROR) -> None:
e_traceback = traceback.format_exception(e.__class__, e, e.__traceback__)
traceback_lines = []
for line in [line.rstrip('\n') for line in e_traceback]:
traceback_lines.extend(line.splitlines())
logger.log(level, traceback_lines.__str__())
그 후 (로그를 분석 할 때) 로그 파일에서 필요한 역 추적 라인을 복사하여 붙여 넣을 수 있습니다.
ex_traceback = ['line 1', 'line 2', ...]
for line in ex_traceback:
print(line)
이익!
이 답변은 위의 우수한 답변에서 작성됩니다.
대부분의 응용 프로그램에서는 logging.exception (e)을 직접 호출하지 않습니다. 다음과 같이 애플리케이션 또는 모듈에 특정한 사용자 정의 로거를 정의했을 것입니다.
# Set the name of the app or module
my_logger = logging.getLogger('NEM Sequencer')
# Set the log level
my_logger.setLevel(logging.INFO)
# Let's say we want to be fancy and log to a graylog2 log server
graylog_handler = graypy.GELFHandler('some_server_ip', 12201)
graylog_handler.setLevel(logging.INFO)
my_logger.addHandler(graylog_handler)
이 경우 로거를 사용하여 다음과 같이 예외 (e)를 호출하십시오.
try:
1/0
except ZeroDivisionError, e:
my_logger.exception(e)
약간의 데코레이터 처리 (아마도 모나드와 리프팅에서 느슨하게 영감을 얻음). Python 3.6 유형 주석을 안전하게 제거하고 이전 메시지 형식 스타일을 사용할 수 있습니다.
fallible.py
from functools import wraps
from typing import Callable, TypeVar, Optional
import logging
A = TypeVar('A')
def fallible(*exceptions, logger=None) \
-> Callable[[Callable[..., A]], Callable[..., Optional[A]]]:
"""
:param exceptions: a list of exceptions to catch
:param logger: pass a custom logger; None means the default logger,
False disables logging altogether.
"""
def fwrap(f: Callable[..., A]) -> Callable[..., Optional[A]]:
@wraps(f)
def wrapped(*args, **kwargs):
try:
return f(*args, **kwargs)
except exceptions:
message = f'called {f} with *args={args} and **kwargs={kwargs}'
if logger:
logger.exception(message)
if logger is None:
logging.exception(message)
return None
return wrapped
return fwrap
데모:
In [1] from fallible import fallible
In [2]: @fallible(ArithmeticError)
...: def div(a, b):
...: return a / b
...:
...:
In [3]: div(1, 2)
Out[3]: 0.5
In [4]: res = div(1, 0)
ERROR:root:called <function div at 0x10d3c6ae8> with *args=(1, 0) and **kwargs={}
Traceback (most recent call last):
File "/Users/user/fallible.py", line 17, in wrapped
return f(*args, **kwargs)
File "<ipython-input-17-e056bd886b5c>", line 3, in div
return a / b
In [5]: repr(res)
'None'
이 솔루션을 수정 None
하여 except
파트 보다 조금 더 의미있는 것을 리턴 할 수도 있습니다 (또는 fallible
인수 에이 리턴 값을 지정하여 솔루션을 일반으로 만들 수도 있습니다 ).
추가 종속성에 대처할 수있는 경우 twisted.log를 사용하면 오류를 명시 적으로 기록 할 필요가 없으며 파일 또는 스트림에 전체 추적 및 시간을 반환합니다.
그것을하는 확실한 방법 format_exc()
은 출력을 사용 하고 파싱하여 관련 부분을 얻는 것입니다.
from traceback import format_exc
try:
1/0
except Exception:
print 'the relevant part is: '+format_exc().split('\n')[-2]
문안 인사
참고 URL : https://stackoverflow.com/questions/5191830/how-do-i-log-a-python-error-with-debug-information
'Programming' 카테고리의 다른 글
MVC의 ViewModel은 무엇입니까? (0) | 2020.02.21 |
---|---|
모든 SDK 라이센스 자동 수락 (0) | 2020.02.21 |
JavaScript를 사용하여 JSON 속성에 새 속성 (요소) 추가 (0) | 2020.02.21 |
Heroku + node.js 오류 (웹 프로세스가 시작 후 60 초 내에 $ PORT에 바인딩하지 못했습니다) (0) | 2020.02.21 |
GCC에서`문자열 상수에서 'char *'`경고로 더 이상 사용되지 않는 변환을 제거하는 방법은 무엇입니까? (0) | 2020.02.21 |