此代碼的工作,因爲被提交到線程池之前被記錄的問題:
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
將被轉換爲字符串並用作記錄回溯的消息。
新的線程意味着新的堆棧。 –
但是,如果像'logger.exception(e)' – garg10may
這樣提交,它會起作用,因爲你在調用'submit'前做了日誌記錄。它實際上會被記錄調用的結果調用,AFAIR應該是'None'。 –