優雅地記錄Python程序日誌一:logging模塊簡介

轉載自 州的先生博客 :https://zmister.com/archives/213.html

前言

在使用 Python 編寫程序的過程中,我們經常使用 print() 函數打印一些信息到控制檯,方便的查看結果和一些調試信息,以判斷程序的運行是否正常。

print() 確實是方便和易用,但是也有一些缺點,比如打印出來的信息不能保存,再次運行程序時,之前打印出來的結果就被清空了。

而對於一些後臺運行的程序,或者出現的異常,比如 Web 應用,直接將信息使用 print() 打印出來,顯然不利於程序出現故障之後的排錯和調試。

這個時候,一個程序日誌記錄器就顯得很有必要了。

日誌器用於跟蹤記錄程序運行時發生的一些事件,一般而言,一條日誌記錄由事件的描述性信息、可選的可變數據組成。

Python 的內置日誌模塊

Python 中內置一個日誌模塊—— logging,通過它我們就可以很方便的在 Python 代碼中記錄簡單的程序日誌。

logging 模塊將日誌分爲了五個等級:

  • DEBUG:調試信息,通常在診斷問題的時候用得着;
  • INFO:普通信息,確認程序安裝預期運行;
  • WARNING:警告信息,表示發生了意想不到的事情,或者指示接下來可能會出現一些問題,但是程序還是繼續運行;
  • ERROR:錯誤信息,程序運行中出現了一些問題,一些功能沒有執行;
  • CRITICAL:危險信息,一個嚴重的錯誤,導致程序無法繼續運行。

上述的五個等級的日誌信息分別使用:logging 模塊的 debug()、info()、warning()、error()、critical() 方法來實現。

默認情況下,logging 使用的日誌級別是 warning,這表示只有在這個級別及其以上級別的日誌信息纔會被記錄,所以默認情況下 debug 信息和 info 信息都不會被顯示出來。

我們來測試一下:

import logging

logging.error("出現了錯誤")
logging.info("打印信息")
logging.warning("警告信息")

運行代碼,控制檯會顯示:

ERROR:root:出現了錯誤
WARNING:root:警告信息
INFO級別的信息,果然沒有顯示出來。

我們使用 logging 模塊的 basicConfig() 方法,修改一個日誌輸出等級爲INFO :

import logging

logging.basicConfig(level=logging.INFO)
logging.error("出現了錯誤")
logging.info("打印信息")
logging.warning("警告信息")

這樣,控制檯中就能夠輸出 INFO 級別的信息了:

ERROR:root:出現了錯誤
INFO:root:打印信息
WARNING:root:警告信息

記錄的日誌信息除了打印到控制檯之外,我們還能夠將其寫入文件中。同樣是使用 basicConfig() 方法進行設置:

import logging

logging.basicConfig(level=logging.INFO,filename='test.log')
logging.error("出現了錯誤")
logging.info("打印信息")
logging.warning("警告信息")

運行程序,會生成一個名爲 test.log 的文本文件,裏面是日誌記錄的內容:
在這裏插入圖片描述
如果我們重複運行上面的代碼,會發現,日誌信息會追加在 test.log 文件的內容後面:
在這裏插入圖片描述
如果不想這樣怎麼辦,同樣在 basicConfig() 方法中使用 filemode 參數進行設置:

import logging

logging.basicConfig(level=logging.INFO,filename='test.log',filemode='w')
logging.error("出現了錯誤")
logging.info("打印信息")
logging.warning("警告信息")

這樣,生成的日誌文件就是一個新的:
在這裏插入圖片描述
在上面輸出的日誌信息我們可以發現,所有的消息都是”日誌級別:角色:消息”這樣的格式輸出的。
如果我們想改變日誌消息的格式呢?同樣使用 basicConfig() 方法,利用其 format 參數進行設置。先來看一個例子:

import logging

logging.basicConfig(level=logging.INFO,filename='test.log',format="%(levelname)s:%(message)s")
logging.error("出現了錯誤")
logging.info("打印信息")
logging.warning("警告信息")

我們設置格式爲消息等級和消息內容。輸出的日誌內容中,已經沒有了root這個信息了:
在這裏插入圖片描述
logging 支持的格式還不止這兩種,我們來看看:

  • %(asctime)s:日誌創建時的普通時間;
  • %(created)f:日誌創建時的時間(由time.time()返回);
  • %(filename)s:文件名;
  • %(funcName)s:調用日誌記錄的函數;
  • %(levelname)s:日誌消息的文本級別;
  • %(levelno)s:日誌消息的數字級別;
  • %(lineno)d:調用日誌消息的行號;
  • %(msecs)d:創建時間的毫秒部分;
  • %(message)s:日誌消息;
  • %(name)s:日誌器的名稱;
  • %(pathname)s:記錄日誌的源文件的路徑名;
  • %(process)d:進程ID;
  • %(processName)s:進程名;
  • %(thread)d:線程ID;
  • %(threadName)s:線程名;
  • %(relativeCreated)d:創建日誌記錄的時間(以毫秒爲單位)

藉助於這些格式,我們可以自定義日誌記錄,比如顯示時間:

import logging

logging.basicConfig(level=logging.INFO,filename='test.log',format="%(levelname)s:%(asctime)s:%(message)s")
logging.error("出現了錯誤")
logging.info("打印信息")
logging.warning("警告信息")

這樣,日誌中除了記錄消息等級、消息信息外,還會記錄上消息創建的時間:
在這裏插入圖片描述
下一篇:優雅地記錄Python程序日誌二:模塊組件化日誌記錄器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章