2017-09-27 100 views
0

logger.exception如果在池中執行,則不顯示堆棧跟蹤,並且將錯誤消息傳遞爲arg。Python - 如何在新線程中獲取堆棧跟蹤

設置:

import logging 
from concurrent.futures import ThreadPoolExecutor 
logger = logging.getLogger('custom') 
ch = logging.StreamHandler() 
logger.addHandler(ch) 
logger.setLevel(logging.INFO) 
executor = ThreadPoolExecutor(3) 

不顯示堆棧跟蹤:

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.exception, e) 

顯示堆棧跟蹤:

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.exception(e)) 
+2

新的線程意味着新的堆棧。 –

+0

但是,如果像'logger.exception(e)' – garg10may

+0

這樣提交,它會起作用,因爲你在調用'submit'前做了日誌記錄。它實際上會被記錄調用的結果調用,AFAIR應該是'None'。 –

回答

2

此代碼的工作,因爲被提交到線程池之前被記錄的問題:

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.exception(e)) 

在現實中,你發送到線程池是什麼None

這不起作用,因爲有一點神奇的logger.exception調用發生,這不,當它的異常處理上下文之外(這當它在另一個線程的運行它會)工作:

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.exception, e) 

它通常有助於檢查文檔。對於.exception() method文檔說:

在此記錄器上記錄級別爲ERROR的消息。參數解釋爲debug()。異常信息被添加到日誌消息中。該方法只能從異常處理程序調用。

.debug()文檔的相關部分是:

logging.debug(MSG,*指定參數時,** kwargs)

日誌與根記錄器級別DEBUG的消息。 msg是消息格式字符串,args是使用字符串格式化運算符合併到msg中的參數。 (請注意,這意味着您可以使用格式字符串中的關鍵字以及單個字典參數。)

在被檢查的kwargs中有三個關鍵字參數:exc_info,如果它不計算爲false,則會導致將異常信息添加到日誌消息中。如果提供了一個異常元組(以sys.exc_info()返回的格式),則使用它;否則,調用sys.exc_info()來獲取異常信息。

所以,這條線:

executor.submit(logger.exception, e) 

將調用原因sys.exc_info()在線程處理的記錄,其中有沒有異常信息被稱爲 - 所以沒有回溯記錄。相反,你想:

executor.submit(logger.exception, "error occurred", exc_info=sys.exc_info()) 

所以在它的最終形式,它會是什麼樣子:

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.exception, "error occurred", exc_info=sys.exc_info()) 

更妙的是避免logger.exception()電話而只使用logger.error()代替:

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.error, "error occurred", exc_info=sys.exc_info()) 

如果您希望將異常消息作爲日誌消息,則可以執行此操作(類似於您在原始代碼中執行的操作):

try: 
    1/0 
except Exception as e: 
    executor.submit(logger.error, e, exc_info=sys.exc_info()) 

e將被轉換爲字符串並用作記錄回溯的消息。

+0

然後我應該用'logger.error,e,exc_info = sys.exc_info()'調用,因爲'logger.exception'只是'logger.error' with'exc_info = True' – garg10may

+0

你很安全的調用logger.exception這裏只要你通過'exc_info'參數提供異常信息,但是,我確實認爲'logger.error'是更好的選擇。 – jszakmeister