很多剛開始寫 Python 的人,習慣用 print() 來查看程式運作狀況。但在專案規模變大時,你很快就會遇到瓶頸:
- 訊息大爆炸:重要錯誤與無關緊要的除錯訊息混在一起,難以閱讀。
- 無法存檔:想要追蹤過去發生的錯誤,卻發現終端機關掉就沒了,只能自己寫程式存檔。
- 來源不明:當有很多檔案時,很難分辨這行訊息到底是從哪個模組印出來的。
這時候,Python 內建的 logging 模組就是你的救星。它能幫你分級管理訊息、自動存檔,並讓除錯變得專業又輕鬆。
1. 快速上手:基本使用方式
使用 logging 非常簡單,只需三個步驟:匯入、設定、輸出。
import logging
# 1. 設定基本配置 (預設等級設為 INFO)
logging.basicConfig(level=logging.INFO)
# 2. 建立 logger (建議使用 __name__ 讓 log 知道是哪個檔案發出的)
logger = logging.getLogger(__name__)
# 3. 輸出不同等級的訊息
logger.debug("這是 debug 訊息(開發除錯用)")
logger.info("這是 info 訊息(一般資訊)")
logger.warning("這是 warning 訊息(警告)")
logger.error("這是 error 訊息(錯誤)")
logger.critical("這是 critical 訊息(嚴重崩潰)")
2. 搞懂「日誌等級 (Log Levels)」
logging 的核心在於「等級」。你可以決定現在只想看「錯誤」,還是想看「所有細節」。
由低到高(嚴重程度)共有五種等級:
| 等級 | 說明 | 適用情境 |
|---|---|---|
| DEBUG | 最詳細的訊息 | 開發時用來追蹤變數、迴圈狀態,除錯用。 |
| INFO | 一般資訊 | 確認程式正如預期執行中(例如:連線成功、任務開始)。 |
| WARNING | 警告訊息 | 程式沒掛掉,但有潛在問題(例如:磁碟空間不足、使用了過期函式)。 |
| ERROR | 錯誤訊息 | 程式某個功能執行失敗,但整體還能跑(例如:存檔失敗)。 |
| CRITICAL | 致命錯誤 | 程式嚴重崩潰,可能無法繼續執行。 |
注意:如果你設定
level=logging.INFO,那麼比 INFO 低階的 DEBUG 訊息就會被自動過濾掉(不顯示)。
3. 讓訊息更清楚:格式化 (Formatting)
預設的輸出有點單調,我們可以加上時間、嚴重等級和訊息內容,讓 Log 一目了然。
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logger.info("格式化後的輸出看起來專業多了")
輸出範例:
2023-10-27 10:30:01,123 - INFO - 格式化後的輸出看起來專業多了
4. 將 Log 存入檔案
在正式環境(Production)中,我們通常沒辦法一直盯著螢幕看,這時需要把 Log 寫入檔案。
logging.basicConfig(
filename="app.log", # 指定檔案名稱
filemode="a", # 'a' 代表 append (附加模式),'w' 代表每次重寫
level=logging.DEBUG,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
這樣設定後,所有的訊息都會自動被寫入 app.log,方便日後查閱。
5. 進階技巧:用環境變數控制 Debug 模式
在開發時我們想看 DEBUG 訊息,但在正式上線時只想看 INFO 或 WARNING。頻繁改程式碼很麻煩,不如用「環境變數」來控制。
程式碼寫法:
import logging
import os
# 從環境變數讀取 LOG_LEVEL,沒有設定則預設為 'INFO'
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
logging.basicConfig(
# 將字串轉換為 logging 的常數 (例如 "DEBUG" -> logging.DEBUG)
level=getattr(logging, log_level, logging.INFO),
format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
logger.debug("這行只有在 DEBUG 模式才看得到")
logger.info("這行在 INFO 模式看得到")
執行方式:
- 一般執行(預設 INFO):
bash python app.py - 開啟除錯模式:
bash LOG_LEVEL=DEBUG python app.py
6. 在多檔案專案中的最佳寫法
當你的專案有多個 .py 檔案時,不要在每個檔案都呼叫 basicConfig(這只要在主程式進入點設定一次就好)。
在其他模組(Module)中,你只需要這樣做:
# utils.py 或其他模組檔案
import logging
# __name__ 會自動帶入模組名稱 (例如 utils)
logger = logging.getLogger(__name__)
def do_something():
logger.info("正在執行某個功能...")
這樣做的好處是,Log 輸出時會顯示 utils,讓你一眼就知道這行訊息是從哪個檔案發出來的,追蹤問題超方便。
7. 總結與最佳實踐
- 小專案用 print,大專案一定要用 logging。
- 善用等級過濾:
- 開發環境(Development):設定為
DEBUG或INFO。 - 正式環境(Production):建議設定為
WARNING或ERROR,避免 Log 檔過大塞爆硬碟。
- 開發環境(Development):設定為
- 使用
__name__:建立 Logger 時務必使用logging.getLogger(__name__)以利追蹤來源。 - 進階學習:如果專案更大,建議研究
Handlers(同時輸出到螢幕和檔案)與RotatingFileHandler(Log 檔太大時自動切割)的功能。