1. 程式人生 > >python優雅的記錄日誌(堆疊追蹤)

python優雅的記錄日誌(堆疊追蹤)

    工作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即可。