除了 Python 內建的 logging 之外,其實還有很多 log 套件可以選擇,例如:
這些套件當初就是為了解決 logging 的不足而開發的,今天要來介紹的是 loguru,它同時也是我在工作上使用的 Log 套件。
老實說,其他套件我沒有用過,最一開始只是因為它的程式碼比較簡潔,排版也比較好看,以及發生錯誤時的 log 可以很完整,就決定使用它了。
Loguru 最大的特色是,它只有一個 logger,要添加設定 (例如:輸出方式、模板、log level 等),只要用 logger.add()
通通搞定。
讓我們來對照一下兩者的差異。首先先看一下 logging 的寫法 (在 [Day 20] 有 Demo 過類似的)
import logging
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler("spam.log")
fh.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
ch.setFormatter(formatter)
logger.addHandler(fh)
logger.addHandler(ch)
再來看 loguru 的寫法
from loguru import logger
import sys
fmt = "{time} - {name} - {level} - {message}"
logger.add("spam.log", level="DEBUG", format=fmt)
logger.add(sys.stderr, level="ERROR", format=fmt)
沒比較沒傷害,相信大家應該立刻感受到 loguru 的簡潔了。
還有很多地方有差別,就不一一列舉出來了
如果想要從 logging 跳槽到 loguru,可以參考這篇 Migration guide
首先,loguru 的安裝指令如下
pip install loguru
接著來試用一下
# log.py
from loguru import logger
import sys
fmt = "{time} - {name} - {level} - {message}"
logger.add("spam.log", level="DEBUG", format=fmt)
logger.add(sys.stderr, level="ERROR", format=fmt)
logger.info("Test Info")
logger.error("Test Error")
接著你就會在 terminal 看到
並且多了一個新檔案 spam.log
,打開來會看到
讓我們來稍微解釋一下~
首先,loguru 也有預設的輸出,也就是在 terminal 看到的五顏六色的 log,然後在我們的程式中,我們又添加了 2 個輸出,一個在 spam.log
,另一個在 terminal,都是用我們自訂的格式,但 log level 分別是 DEBUG
和 ERROR
,所以我們在 terminal 只會看到一筆我們自訂格式的 log,但卻可以在 spam.log
看到兩筆。
同樣,我們來看一下這個範例
# main.py
from fastapi import FastAPI
from log import logger, init_logger
app = FastAPI()
init_logger()
@app.get("/")
async def root():
logger.info("Logger Info")
logger.error("Logger Error")
print("Hi")
return {"message": "Hello World"}
# log.py
from loguru import logger
import sys
def init_logger():
fmt = "{time} - {name} - {level} - {message}"
logger.add("spam.log", level="DEBUG", format=fmt)
logger.add(sys.stderr, level="ERROR", format=fmt)
可以在 terminal 看到 3 筆 loguru 的 log
而 spam.log
內則是再多了 2 筆 (我沒有刪掉上面的測試結果)
看到這個凌亂的畫面,我們可以利用昨天介紹的方法,去把預設的 uvicorn 的 logger 的設定改掉。
或是大家可以參考這個 Gist 上的範例,裡面有比較完整的做法與程式碼
不過這個範例的作者後來覺得 structlog 比較符合他的期待,因此有放上另一個範例
今天我們簡單地介紹了 loguru 的使用方法,明天預計會回頭介紹 log 與 middleware 的整合 (之前在 [Day 19] 有先輕描淡寫提過 XD)