HOWTO · Python
在 Python 中記錄到標準輸出 stdout
我們可以使用 logging.basicConfig() 和 logging.StreamHandler() 函式在 Python 中記錄到標準輸出。
本頁內容
若要將 Python 記錄訊息送至標準輸出(stdout),請在 logging.basicConfig() 中設定 stream=sys.stdout。若需要更多控制,可以將 logging.StreamHandler(sys.stdout) 附加至記錄器。若要讓相同記錄同時輸出至主控台和檔案,請在串流處理常式之外另行使用 FileHandler。
使用 Python 的 logging.basicConfig() 將記錄輸出至 stdout
若要為整個應用程式設定簡單的記錄方式,logging.basicConfig() 會設定根記錄器。它的 stream 參數用來選擇輸出串流;預設情況下,記錄會寫入 sys.stderr。將此參數設為 sys.stdout,即可把記錄導向標準輸出。level 決定哪些記錄可通過根記錄器,format 則控制每行輸出的格式。
import logging
import sys
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s: %(message)s",
stream=sys.stdout,
)
logging.info("Application started")
INFO: Application started
basicConfig() 是用來設定根記錄器的一次性便利方法。如果應用程式的其他部分已經為根記錄器加入處理常式,之後呼叫 basicConfig() 會保留既有設定,因此在這裡變更 stream 不會重新導向輸出。Python 3.8 及後續版本可使用 force=True,先移除既有的根處理常式,再套用這項設定。只有在你的程式負責取代應用程式的記錄設定時才使用它;否則,請在應用程式進入點設定一次記錄方式。
filename 和 filemode 選項用來設定檔案輸出:filename 指定檔案名稱,filemode 控制檔案的開啟方式,預設為附加模式("a")。呼叫 basicConfig() 時不要同時傳入 filename 和 stream;在這裡選擇一種目的地即可。若要將記錄同時送至標準輸出和檔案,請像下方範例一樣使用不同的處理常式。另外,除非使用 force=True(Python 3.8 及後續版本提供),否則 basicConfig() 只會在根記錄器尚未有任何處理常式時進行設定。
使用 Python 的 logging.StreamHandler() 將記錄輸出至 stdout
若要控制具名記錄器或組合多個輸出目的地,請明確建立處理常式。logging.StreamHandler() 預設會寫入 sys.stderr,因此請明確傳入 sys.stdout。記錄器層級和處理常式層級都會影響哪些記錄能輸出;記錄必須同時通過兩者。此範例會建立一個 stdout 處理常式和一個檔案處理常式,再將兩者附加至同一個記錄器。
import logging
import sys
import tempfile
from pathlib import Path
log_path = Path(tempfile.gettempdir()) / "python-logging-example.log"
logger = logging.getLogger("example")
logger.setLevel(logging.INFO)
logger.propagate = False
formatter = logging.Formatter("%(levelname)s: %(message)s")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(formatter)
file_handler = logging.FileHandler(log_path, mode="w", encoding="utf-8")
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
logger.addHandler(file_handler)
logger.info("Application started")
for handler in (stdout_handler, file_handler):
handler.close()
logger.removeHandler(handler)
INFO: Application started
每個處理常式都會將記錄套用自己的格式,並寫入各自的目的地。檔案會建立在系統的暫存目錄中,mode="w" 則會在每次執行時覆寫範例檔案。在長時間執行的應用程式中,請設定一次處理常式,不要反覆新增;重複的處理常式可能會讓同一筆記錄出現不只一次。在正式環境中,請妥善管理檔案路徑和處理常式的生命週期。
結論
若要快速設定根記錄器,請使用 logging.basicConfig() 並設定 stream=sys.stdout。若需要控制具名記錄器、自訂處理常式設定或多個輸出目的地,請選擇 logging.StreamHandler(sys.stdout)。未明確指定串流的 StreamHandler 會寫入 stderr;若要同時輸出至檔案和主控台,則需要分別使用串流處理常式和檔案處理常式。