Python logging 日誌記錄

在開發正式的應用程式時,使用 print() 來除錯並不是一個好習慣。Python 內建的 logging 模組提供了分級記錄、輸出到檔案、自定義格式等強大功能,是專業開發者的必備技能。

為什麼不用 print()?

  1. 等級區分:可以區分是一般資訊 (INFO)、警告 (WARNING) 還是嚴重錯誤 (ERROR)。
  2. 多重輸出:可以同時顯示在終端機並存入檔案。
  3. 格式化:自動包含時間、程式碼行數、執行緒資訊等。
  4. 靈活控制:可以只針對特定等級以上的日誌進行顯示。

基礎用法

日誌等級 (Levels)

由低到高分別為:

  • DEBUG:詳細診斷資訊。
  • INFO:程式正常運作的確認訊息。
  • WARNING:潛在問題警告(預設顯示等級)。
  • ERROR:程式發生錯誤,但仍能運作。
  • CRITICAL:嚴重錯誤,程式可能無法繼續執行。
import logging

# 基礎配置
logging.basicConfig(level=logging.INFO)

logging.debug("這條不會顯示,因為等級低於 INFO")
logging.info("程式啟動中...")
logging.warning("記憶體用量偏高")
logging.error("找不到該檔案")
logging.critical("資料庫連線中斷!")

進階配置

通常我們會將日誌存入檔案,並設定特定的格式。

import logging

logging.basicConfig(
    filename='app.log',      # 存入檔案
    filemode='a',            # a 代表追加,w 代表覆蓋
    level=logging.DEBUG,     # 記錄 DEBUG 以上的所有等級
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

logging.info("這條訊息會存入 app.log 檔案中")

常用的格式化變數 (Format Variables)

  • %(asctime)s:人類可讀的時間。
  • %(levelname)s:日誌等級名稱。
  • %(message)s:你傳入的日誌文字。
  • %(filename)s:執行的檔案名稱。
  • %(lineno)d:程式碼所在的行號。

Loggers, Handlers 與 Formatters (正式架構)

在大型專案中,我們會建立一個 logger 物件,並為其分配不同的輸出路徑(Handlers)。

import logging

# 1. 建立 Logger 物件
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)

# 2. 建立控制台 Handler (輸出到終端機)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.WARNING)

# 3. 建立檔案 Handler (輸出到檔案)
file_handler = logging.FileHandler('error.log')
file_handler.setLevel(logging.ERROR)

# 4. 建立並設定格式
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

# 5. 加入 Logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 測試
logger.warning("這會顯示在終端機")
logger.error("這會同時顯示在終端機與存入 error.log")

總結

  • 初學者可以使用 logging.basicConfig() 快速設定。
  • 正式專案應使用 getLogger() 並配置不同的 Handler 以便靈活管理。
  • 養成記錄日誌的習慣,能大幅縮短未來維護與線上排錯的時間。