python logging 模塊詳解

 

Python 中的 logging 模塊可讓你跟蹤代碼運行時的事件,當程序崩潰時能夠查看日誌而且發現是什麼引起了錯誤。Log 信息有內置的層級——調試(debugging)、信息(informational)、警告(warnings)、錯誤(error)和嚴重錯誤(critical)。你也能夠在 logging 中包含 traceback 信息。無論是小項目仍是大項目,都推薦在 Python 程序中使用 logging。本文將簡單清晰地介紹如何使用 logging 模塊。小程序

爲何使用 logging?

當你運行一個 Python 腳本時,你可能想要知道腳本的哪一個部分在執行,而且檢視變量的當前值。測試

一般,能夠只使用 print() 打印出你想要的信息。在小程序中,可能靠這個就足夠了。debug

但問題是,當你處理有不少個模塊的大項目時,就須要一個更加靈活的方法。3d

爲何?調試

由於代碼須要經歷開發、調試、審查、測試或者上線等不一樣階段。在開發時你想要打印的信息類型可能和上線後你想看到的信息類型徹底不一樣。日誌

也就是說,在「測試」時,你可能只想看警告和錯誤信息,然而在「調試」時,你可能還想看到跟調試相關的信息。code

若是你還想打印出使用的模塊以及代碼運行的時間,那麼你的代碼很容易變得混亂。orm

使用 logging 模塊,這些問題就能很容易地解決。blog

logging 模塊能夠:事件

  1. 控制信息層級,僅記錄須要的信息。

  2. 控制顯示或者保存日誌的時機。

  3. 使用內置信息模板控制日誌格式。

  4. 知曉信息來自於哪一個模塊。

基本 logging 例子

logging 模塊是 Python 的標準庫,要使用 logging,只須要使用 logging.basicConfig() 進行基本設置。事實上,這也是可選的。

而後就能夠調用 logging.{level}(message) 在控制檯中顯示信息。

import logging
logging.basicConfig(level=logging.INFO)

def hypotenuse(a, b):
    """計算三角形斜邊"""
    return (a**2 + b**2)**0.5

logging.info("{a}, {b} 的斜邊是 {c}".format(a=3, b=4, c=hypotenuse(a=3, b=4)))
#> INFO:root:3, 4 的斜邊是 5.0

打印出的日誌信息遵循默認格式: {LEVEL}:{LOGGER}:{MESSAGE}

上面的例子中, LEVEL 就是 INFO,由於調用的是 logging.info()

LOGGER 爲 root,由於這是默認 logger。

logger(日誌記錄器)相似於一個實體,你能夠建立並配置它來記錄不一樣類型和格式的消息。

你能夠配置一個輸出到控制檯的 logger 和另外一個將日誌發送到文件的 logger,它們具備不一樣的日誌記錄級別,而且特定於給定模塊。

最後,輸出的信息就是我傳遞給 logging.info() 的字符串。

那麼若是不設置 logging.basicConfig(level=logging.INFO) 會怎麼樣?

答案是 日誌信息不會被打印出來

爲何?要知道這個須要先了解 logging 的級別。

logging 的 5 個級別

logging 有 5 個不一樣層次的日誌級別,能夠將給定的 logger 配置爲這些級別:

  1. DEBUG:詳細信息,用於診斷問題。Value=10。

  2. INFO:確認代碼運行正常。Value=20。

  3. WARNING:意想不到的事情發生了,或預示着某個問題。但軟件仍按預期運行。Value=30。

  4. ERROR:出現更嚴重的問題,軟件沒法執行某些功能。Value=40。

  5. CRITICAL:嚴重錯誤,程序自己可能沒法繼續運行。Value=50。

如今,讓咱們回答以前提出的問題。默認 logger 是 root,其默認的 basicConfig 級別是 WARNING。也就是說,只有來自 logging.warning或者更高級別的信息纔會被記錄下來。

所以,logging.info() 中的信息不會被打印出來。這也是爲何 basicConfig 被設爲 INFO

若是級別使用 logging.ERROR 代替,只有來自 logging.error 和 logging.critical 的信息會被記錄。

import logging
logging.basicConfig(level=logging.ERROR)

def hypotenuse(a, b):
    """計算三角形斜邊"""
    return (a**2 + b**2)**0.5

kwargs = {'a':3, 'b':4, 'c':hypotenuse(3, 4)}

logging.debug("a = {a}, b = {b}".format(**kwargs))
logging.info("{a}, {b} 的斜邊是 {c}".format(**kwargs))
logging.warning("a={a} 和 b={b} 相等".format(**kwargs))
logging.error("a={a} 和 b={b} 不能爲負".format(**kwargs))
logging.critical("{a}, {b} 的斜邊是 {c}".format(**kwargs))

#> ERROR:root:a=3 和 b=4 不能爲負
#> CRITICAL:root:3, 4 的斜邊是 5.0

將日誌記入文件

要從 root logger 將日誌消息發送到文件,須要在 logging.basicConfig() 中設置 file 參數:

import logging
logging.basicConfig(level=logging.INFO, filename='sample.log')

如今,全部後續日誌消息都將直接記錄到當前工做目錄中的「sample.log「文件。若是要將其記錄到另外一個目錄中的文件,請給出完整的文件路徑。

如何更改 logging 格式

logging 模塊提供了向日志消息添加各類詳細信息的速記表。

fig

讓咱們更改日誌信息格式以顯示 TIMELEVEL 和 MESSAGE

import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s :: %(levelname)s :: %(message)s')

logging.info("噹噹噹!")
#> 2019-03-10 19:41:09,057 :: INFO :: 噹噹噹!

不要對全部模塊使用 root logger

讓咱們看下面的代碼:

# 1. myprojectmodule.py
import logging
logging.basicConfig(filename='module.log')

#-----------------------------

# 2. main.py (從 myprojectmodule.py 導入代碼)
import logging
import myprojectmodule  # 運行 myprojectmodule.py 中的代碼,將生成 `module.log` 文件

logging.basicConfig(filename='main.log')  # 無效!

若是項目中有一個或多個模塊。這些模塊使用基本根模塊。而後,當導入模塊 myprojectmodule.py 時,將運行該模塊的全部代碼並配置 logger。

一旦配置好,main 文件中的 root logger 將不能再更改 root logger 設置。由於,一旦設置好 logging.basicConfig(),就不能再更改它。

若是想在不一樣文件中使用不一樣 logger,就須要建立一個新的 logger。

如何建立一個新的 logger?

可使用 logger.getLogger(name) 方法建立一個新的 logger。若是存在同名的 logger,則將使用該 logger。

能夠給 logger 取任何名字,可是一般使用 __name__ 變量:

相關文章
相關標籤/搜索