Python logging 模組使用指南

Wray_Zheng發表於2017-05-03

記錄日誌是追蹤事件的一種手段。通過新增日誌,開發者可以清楚地瞭解發生了哪些事件,包括出現了哪些錯誤。logging 模組提供了一系列便捷的函式,用於簡單的日誌記錄。它們分別是 debug(), info(), warning(), error()critical()

簡單示例

下面是一個非常簡單的示例:

import logging
logging.warning('Watch out!')   # 列印一條資訊到命令列
logging.info('I told you so')   # 不會列印任何東西複製程式碼

如果你執行著幾行程式碼,你會看到命令列中輸出以下內容:

WARNING:root:Watch out!複製程式碼

由於 logging 模組預設的級別為 WARNING,因此 INFO 級別的日誌不會被列印出來。輸出的日誌包含了級別和事件的描述。root 為預設 logger 的名字,我們可以手動更改它,並且自定義日誌的輸出格式。

記錄日誌到檔案

很多情況下,我們會把日誌記錄到檔案中,接下來我們就來看看具體的操作。請重新開啟一個 python 直譯器,而不要直接使用上述例子所用的直譯器,確保 logging 模組能夠被正確配置。

import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')複製程式碼

如果我們開啟 example.log 檔案,可以看到以下內容:

DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too複製程式碼

這個例子告訴你如何設定日誌級別,從而控制要記錄的日誌。由於我們在這個例子中設定的級別是 DEBUG,因此所有的日誌都會被記錄下來。

多個模組記錄日誌

如果你的程式包含了多個模組,這裡有一個例子向你展示瞭如何組織它們的日誌輸出:

# myapp.py
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()複製程式碼
# mylib.py
import logging

def do_something():
    logging.info('Doing something')複製程式碼

如果你執行 myapp.py 檔案,你會在 myapp.log 檔案中看到以下內容:

INFO:root:Started
INFO:root:Doing something
INFO:root:Finished複製程式碼

記錄變數的資料

要記錄變數的資料,可以使用一個格式串來格式化輸出,並將變數作為引數傳遞給日誌記錄函式。

import logging
logging.warning('%s before you %s', 'Look', 'leap!')複製程式碼

輸出內容:

WARNING:root:Look before you leap!複製程式碼

你也可以使用 python 自帶的字串格式化函式:

import logging
logging.warning('{} before you {}'.format('Look', 'leap!'))複製程式碼

自定義日誌格式

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')複製程式碼

輸出如下:

DEBUG:This message should appear on the console
INFO:So should this
WARNING:And this, too複製程式碼

注意到之前的例子中出現的 root 在這裡已經消失了。要了解所有能出現在格式串裡的東西,請參考 LogRecord attributes。但如果只是簡單使用,你只需要 levelname(級別)、message(事件描述,包括變數資料)以及事件發生的時間,這點將在下面講解。

記錄日期和時間

要在日誌中顯示日期和時間,你需要在格式串中加入 %(asctime)s:

import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')複製程式碼

輸出如下:

2010-12-12 11:41:42,612 is when this event was logged.複製程式碼

格式串中的時間格式引數與 time.strftime() 中支援的引數相同。

logging 進階指南

logging 模組採取了模組化的方式並提供了幾個元件的類別:logger、handler、filter、formatter。

  • logger 提供了程式碼中直接使用的介面
  • handler 用於向目的地傳送日誌記錄
  • filter 用於過濾特定的日誌記錄
  • formatter 指定了日誌記錄最終的輸出樣式

日誌事件資訊在一個 LogRecord 例項中的 logger、handler、filter 和 formatter 之間傳遞。

一個給 logger 命名的好習慣是使用模組級別的 logger。在每一個需要記錄日誌的模組內使用以下方式來給 logger 命名:

logger = logging.getLogger(__name__)複製程式碼

這種情況下,logger 的名字會追蹤包/模組的層次結構,並且我們可以直觀地看到事件是由哪個模組記錄的。

層次結構中最頂級的 logger 稱為 root logger。當我們呼叫 logging 模組的 debug(), info(), warning(), error()critical() 函式時,會使用 root logger 對應的同名方法。這些函式與 root logger 中的同名方法具有相同的引數簽名。root logger 在輸出時名字為 root

當然,我們也可以將資訊記錄到不同的目的地。我們可以將日誌記錄到檔案、HTTP GET/POST 位置、郵件(通過 SMTP)、普通套接字或系統專用的日誌機制,例如 syslog 或 Windows NT 事件日誌。目的地由 handler 類進行處理。如果內建的 handler 類沒有滿足你的要求,你可以建立一個自己的日誌目的地類。

預設情況下,不會給日誌資訊設定目的地。你可以使用 basicConfig() 來指定目的地,正如之前所給的例子一樣。如果你呼叫了 debug(), info(), warning(), error()critical() 函式,它們會檢查是否設定了目的地,如果未設定目的地,則預設使用命令列(sys.stderr)作為目的地,並使用預設的格式來顯示資訊。

basicConfig() 函式預設的格式為:

severity:logger name:message複製程式碼

你可以通過傳遞一個格式串以及格式引數給 basicConfig() 來改變輸出格式。關於格式串構建的所有選項,請參考 Formatter Objects

參考文章:Logging HOWTO

作者:Wray Zheng
原文連結: www.codebelief.com/article/201…

相關文章