Python 寫 log 示範

在 python 內建的 logging 中,log 有五種等級,由低到高分別是:
  • debug: 除錯使用,包含各種囉唆繁瑣的訊息
  • info: 資訊,一般的紀錄
  • warning: 發生預期外的事情
  • error: 錯誤,某些功能可能無法正常執行
  • critical: 嚴重錯誤,程式本身可能無法正常執行
log 的使用方式如下:
    
import logging


logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
    

執行顯示訊息如下:
    
WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message
    

會發現 debug 和 info 的資訊沒有顯示,可以在程式一開始執行時加入下面的程式碼來定要顯示的 log 等級:
    
import logging


logging.basicConfig(level=logging.DEBUG)

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
    

輸出到文件中

如果在 控制台/指令視窗 中就可以看到訊息了,為什麼還需要使用 log?最主要的目的就是寫到檔案中,方便我們容易的尋找錯誤,不會程式關閉後紀錄就不見了。

要寫到檔案中也非常的簡單:
    
import logging


logging.basicConfig(
    level=logging.DEBUG,  # log 紀錄等級
    filename='app.log',  # log 檔案名稱
    format='%(name)s:%(levelname)s:%(message)s',  # log 訊息格式
)

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
    

執行後到執行檔(很可能是 main.py)旁邊會發現多了一個 app.log 檔案,log 被成功寫入到檔案中了,內容如下:
    
root:DEBUG:This is a debug message
root:INFO:This is an info message
root:WARNING:This is a warning message
root:ERROR:This is an error message
root:CRITICAL:This is a critical message
    

要紀錄時間也很簡單,把 format 換成下面這樣:
    
logging.basicConfig(
    level=logging.DEBUG,  # log 紀錄等級
    filename='app.log',  # log 檔案名稱
    format='%(asctime)s %(name)s:%(levelname)s:%(message)s',  # log 訊息格式
)
    

輸出訊息:
    
2024-01-29 22:10:54,808 root:DEBUG:This is a debug message
2024-01-29 22:10:54,808 root:INFO:This is an info message
2024-01-29 22:10:54,809 root:WARNING:This is a warning message
2024-01-29 22:10:54,809 root:ERROR:This is an error message
2024-01-29 22:10:54,809 root:CRITICAL:This is a critical message
    

寫檔案的模式

    
logging.basicConfig(
    level=logging.DEBUG,  # log 紀錄等級
    filename='app.log',  # log 檔案名稱
    filemode='a',  # log 檔案寫入模式
    format='%(asctime)s %(name)s:%(levelname)s:%(message)s',  # log 訊息格式
)
    

檔案寫入模式常見的有兩種, a 和 w :
  • a: filemode 的預設值,log 會附加到原本的檔案後面,會持續增加
  • w: 覆蓋既有內容(將舊的 log 清除),寫入新的 log
在測試時可以使用 w 模式,這樣 log 檔案內就只會保留最後一次執行時的內容,方便測試,不過在正式環境中最好使用預設的 a 模式,避免 log 被覆蓋,無法尋找錯誤。

咦?指令視窗中的 log 訊息怎麼不會顯示了?

log 輸出到文件中指令視窗依然顯示 log

這個也很簡單,一行就可以恢復,讓指令視窗顯示 log 的同時也將 log 寫到檔案中:
    
import logging


logging.basicConfig(
    level=logging.DEBUG,  # log 紀錄等級
    filename='app.log',  # log 檔案名稱
    format='%(name)s:%(levelname)s:%(message)s',  # log 訊息格式
)

logging.getLogger().addHandler(logging.StreamHandler())

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
    

輸出範例:
    
This is a debug message
This is an info message
This is a warning message
This is an error message
This is a critical message
    

不過這樣就不能自訂顯示的格式了,可以使用下面的這種方式解決:
    
import logging


logging.basicConfig(
    level=logging.DEBUG,  # log 紀錄等級
    filename='app.log',  # log 檔案名稱
    format='%(name)s:%(levelname)s:%(message)s',  # log 訊息格式
)

consoleHandler = logging.StreamHandler()
logFormatter = logging.Formatter("%(asctime)s %(name)s:%(levelname)s:%(message)s")
consoleHandler.setFormatter(logFormatter)
logging.getLogger().addHandler(consoleHandler)

logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
    

輸出範例:
    
2024-01-29 22:14:20,454 root:DEBUG:This is a debug message
2024-01-29 22:14:20,454 root:INFO:This is an info message
2024-01-29 22:14:20,455 root:WARNING:This is a warning message
2024-01-29 22:14:20,455 root:ERROR:This is an error message
2024-01-29 22:14:20,455 root:CRITICAL:This is a critical message
    



參考資料:
Python.docs - Logging HOWTO

留言