python優雅的記錄日誌(堆疊追蹤)
阿新 • • 發佈:2018-12-20
工作3年,解決線上問題無數。日誌對於定位和分析問題的重要行不言而喻。那麼python怎麼優雅的記錄日誌呢?
首先,python記錄日誌,首選是logging模組,沒有啥爭議。
日誌的一般寫法是這樣的:
logging.info('info message')
logging.error('error message')
這種日誌一般作用不大,只能定位到程式正常執行時執行到哪一步和列印輸出一些資訊。對於一些異常之列的資訊,我們需要使用try:execpt獲取。
很多人是這樣記錄異常日誌的:
>>> def test(a): ... int(a) >>> try: ... test("a") ... except Exception as e: ... print(e.message) ... invalid literal for int() with base 10: 'a'
開發人員只看到一行python的報錯,是很難定位問題的。我們需要錯誤的堆疊資訊,定位到錯誤的源頭,例如:
>>> try: ... test("a") ... except Exception as e: ... logging.exception(e) ... ERROR:root:invalid literal for int() with base 10: 'a' Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 2, in test ValueError: invalid literal for int() with base 10: 'a'
使用logging.exception 的話就可以拿到堆疊資訊。是不是很神奇,我們一起來看看logging的原始碼,看它為啥能拿到堆疊資訊。
對比error
發現,exception其實是呼叫error的,唯一的不同時,有一個預設引數exc_info=True。。。一直檢視它的呼叫關係,到了這裡:
看到這裡,應該都清楚了,其實他使用的是sys.exc_info(),這個python內建sys函式。。。
明白了logging.exception的原理後,我們就可以這樣定義日誌了:
>>> try: ... test("a") ... except Exception as e: ... logging.error("執行test函式報錯", exc_info=True) ... ERROR:root:執行test函式報錯 Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 2, in test ValueError: invalid literal for int() with base 10: 'a'
這樣,不僅可以自定義logging,還可以列印堆疊資訊。info同理,只要把error改成info即可。