2017-05-12 3 views
3

이것은 정말 간단한 질문이지만, Google 검색, 문서 및 기타 여러 가지 SO 스레드를 읽은 후에 대답을 찾지 못합니다. 파이썬 표준 로깅으로 예외를 어떻게 로그합니까? 하나의 작은 주름은 제가 미래로부터 예외를 얻고 있다는 것입니다. 나는 except 예외 핸들러를 직접 쓰지 않을 것이다. 이상적으로는 예외 메시지, 스택 추적, 보낸 여분의 메시지 및 예외 유형을 얻게됩니다. 여기 내 문제를 보여주는 간단한 프로그램입니다 :미래의 단순한 파이썬 로깅 예외

import logging 
from concurrent.futures import ThreadPoolExecutor 

logger = logging.getLogger(__name__) 


def test_f(a, b=-99, c=50): 
    logger.info("test_f a={} b={} c={}".format(a, b, c)) 


def future_callback_error_logger(future): 
    e = future.exception() 
    if e is not None: 
     # This log statement does not seem to do what I want. 
     # It logs "Executor Exception" with no information about the exception. 
     # I would like to see the exception type, message, and stack trace. 
     logger.error("Executor Exception", exc_info=e) 


def submit_with_log_on_error(executor, func, *args, **kwargs): 
    future = executor.submit(func, *args, **kwargs) 
    future.add_done_callback(future_callback_error_logger) 


if __name__ == "__main__": 
    logging.basicConfig(level="DEBUG") 

    logger.info("start") 
    executor = ThreadPoolExecutor(max_workers=5) 

    # This will work. 
    submit_with_log_on_error(executor, test_f, 10, c=20) 
    # This will intentionally trigger an error due to too many arguments. 
    # I would like that error to be properly logged. 
    submit_with_log_on_error(executor, test_f, 10, 20, 30, 40) 
    # This will work. 
    submit_with_log_on_error(executor, test_f, 50, c=60) 

    executor.shutdown(True) 
    logger.info("shutdown") 

답변

2

logger.exception를 사용하여 역 추적을 얻으려면, 당신은 블록을 제외하고 내부에 있어야합니다. future.exception()을 확인하는 대신 인 경우 예외가있는 경우 future.result()을 입력하고 은 예외 (있는 경우)를 발생시킵니다.

그래서, try이 대신 (웃기려는 의도가 없으며) :

def future_callback_error_logger(future): 
    try: 
     future.result() 
    except Exception: 
     logger.exception("Executor Exception") 
+0

와우, 일이. 감사! – clay