Loguru是一個功能強大且易於使用的開源Python日誌記錄庫。它建立在Python標準庫中的logging模組之上,並提供了更加簡潔直觀、功能豐富的介面。Logging模組的使用見:Python日誌記錄庫logging總結。Loguru官方倉庫見:loguru,loguru官方文件見: loguru-doc。
Loguru的主要特點包括:
- 簡單易用:無需複雜的配置和定製即可實現基本的日誌記錄和輸出。
- 靈活的日誌格式:支援自定義日誌格式,並提供豐富的格式化選項。
- 豐富的日誌級別:支援多種日誌級別,例如DEBUG、INFO、WARNING、ERROR和CRITICAL。
- 多種日誌目標:可以將日誌輸出到終端、檔案、電子郵件、網路伺服器等目標。
- 強大的日誌處理功能:支援日誌過濾、格式化、壓縮、旋轉等功能。
- 支援非同步日誌記錄:能夠極大地提升日誌記錄的效能。
- 支援跨程序、跨執行緒的日誌記錄:可以安全地記錄多程序、多執行緒應用程式的日誌。
Loguru與logging是Python中常用的兩個日誌記錄庫,但兩者在功能和易用性方面存在一些差異,如下所示:
特性 | Loguru | logging |
---|---|---|
易用性 | 更簡單易用 | 相對複雜 |
日誌格式 | 更靈活 | 較簡單 |
日誌級別 | 更豐富 | 較少 |
日誌目標 | 更多種類 | 較少 |
日誌處理功能 | 更強大 | 較弱 |
非同步日誌記錄 | 支援 | 不支援 |
跨程序、跨執行緒支援 | 支援 | 支援 |
總的來說,loguru在易用性、功能性和效能方面都優於logging。如果要一個簡單、強大且易於使用的日誌系統,loguru是一個很好的選擇。而如果只是需要快速輸出一些除錯資訊,print可能就足夠了。不過,對於生產環境,使用loguru或其他日誌系統通常會更加合適。
Loguru安裝命令如下:
pip install loguru
# 檢視loguru版本
import loguru
print(loguru.__version__) # 輸出:0.7.2
- 1 使用說明
- 1.1 基礎用法
- 1.2 日誌配置
- 1.3 進階使用
- 2 參考
1 使用說明
1.1 基礎用法
簡單使用
Loguru的核心概念是隻有一個全域性的日誌記錄器,也就是logger。這個設計使得日誌記錄變得非常簡潔和一致。使用Loguru時,你不需要建立多個日誌例項,而是直接使用這個全域性的logger來記錄資訊。這不僅減少了配置的複雜性,也使得日誌管理更加集中和高效。
from loguru import logger
logger.debug("這是一個除錯資訊")
輸出:
2024-06-29 19:57:44.506 | DEBUG | __main__:<module>:3 - 這是一個除錯資訊
Loguru日誌輸出預設格式如下:
- 時間戳:表示日誌記錄的具體時間,格式通常為年-月-日 時:分:秒.毫秒。
- 日誌級別:表示這條日誌的嚴重性級別。
- 程序或執行緒標識:表示日誌來自哪個模組或指令碼。
__main__
表示日誌來自主模組。如果是其他檔案會顯示檔名。 - 檔名和行號:記錄日誌訊息的函式名和行號。
- 日誌訊息:實際的日誌內容,此外loguru支援使用顏色來區分不同的日誌級別,使得日誌輸出更加直觀.
日誌等級
Loguru可以透過簡單的函式呼叫來記錄不同級別的日誌,並自動處理日誌的格式化和輸出。這一特點可以讓使用者專注於記錄重要的資訊,而不必關心日誌的具體實現細節。Loguru支援的日誌級別,按照從最低到最高嚴重性排序:
- TRACE: 最詳細的日誌資訊,用於追蹤程式碼執行過程。Loguru預設情況下使用DEBUG級別作為最低日誌記錄級別,而不是TRACE級別。這是因為TRACE級別會產生大量的日誌資訊。
- DEBUG: 用於記錄詳細的除錯資訊,通常只在開發過程中使用,以幫助診斷問題。
- INFO: 用於記錄常規資訊,比如程式的正常執行狀態或一些關鍵的操作。
- SUCCESS: 通常用於記錄操作成功的訊息,比如任務完成或資料成功儲存。
- WARNING: 用於記錄可能不是錯誤,但需要注意或可能在未來導致問題的事件。
- ERROR: 用於記錄錯誤,這些錯誤可能會影響程式的某些功能,但通常不會導致程式完全停止。
- CRITICAL: 用於記錄非常嚴重的錯誤,這些錯誤可能會導致程式完全停止或資料丟失。
from loguru import logger
logger.debug("這是一條跟蹤訊息")
logger.debug("這是一條除錯資訊")
logger.info("這是一條普通訊息")
logger.success("操作成功完成")
logger.warning("這是一條警告資訊")
logger.error("這是一條錯誤資訊")
logger.critical("這是一條嚴重錯誤資訊")
輸出:
2024-06-29 19:58:11.535 | DEBUG | __main__:<module>:3 - 這是一條跟蹤訊息
2024-06-29 19:58:11.536 | DEBUG | __main__:<module>:4 - 這是一條除錯資訊
2024-06-29 19:58:11.536 | INFO | __main__:<module>:5 - 這是一條普通訊息
2024-06-29 19:58:11.537 | SUCCESS | __main__:<module>:6 - 操作成功完成
2024-06-29 19:58:11.537 | WARNING | __main__:<module>:7 - 這是一條警告資訊
2024-06-29 19:58:11.538 | ERROR | __main__:<module>:8 - 這是一條錯誤資訊
2024-06-29 19:58:11.538 | CRITICAL | __main__:<module>:9 - 這是一條嚴重錯誤資訊
1.2 日誌配置
在loguru中,add函式用於新增日誌處理器。這個函式用於指定日誌訊息應該被髮送到何處,例如控制檯、檔案或其他自定義的目的地。add函式主要引數介紹如下:
sink
: 定義日誌訊息的輸出位置,可以是檔案路徑、標準輸出(stdout)、標準錯誤(stderr,預設)或其他自定義的輸出位置。format
: 指定日誌訊息的格式,可以是簡單的字串,也可以是格式化字串,支援各種欄位插值。level
: 設定處理程式處理的日誌訊息的最低階別。比如設定為DEBUG,則處理程式將處理所有級別的日誌訊息。filter
: 可選引數,用於新增過濾器,根據特定的條件過濾掉不需要的日誌訊息。colorize
: 布林值,指定是否對日誌訊息進行著色處理,使日誌在控制檯中更易於區分。serialize
: 布林值,指定是否對日誌訊息進行序列化處理,通常與enqueue=True
一起使用,以確保多執行緒安全。enqueue
: 布林值,指定是否將日誌訊息放入佇列中處理,用於多執行緒應用中避免阻塞。backtrace
: 布林值或字串,指定是否記錄回溯資訊,預設為False
。diagnose
: 布林值,啟用後,會在處理程式內部出現錯誤時記錄診斷資訊。rotation
: 日誌檔案輪換的配置,支援按大小或時間進行日誌檔案的輪換。retention
: 用於設定日誌檔案的保留時間。compression
: 布林值,指定是否對輪換後的日誌檔案進行壓縮處理。
from loguru import logger
import sys
# 終端顯示不受該段程式碼設定
# 新增一個日誌處理器,輸出到檔案
# 設定日誌最低顯示級別為INFO,format將設定sink中的內容
# sink連結的本地檔案,如不存在則新建。如果存在則追寫
logger.add(sink="myapp.log", level="INFO", format="{time:HH:mm:ss} | {message}| {level}")
# debug結果不被顯示到本地檔案
logger.debug("這是一條除錯資訊")
logger.info("這是一條普通訊息")
輸出:
2024-06-29 19:58:56.159 | DEBUG | __main__:<module>:11 - 這是一條除錯資訊
2024-06-29 19:58:56.159 | INFO | __main__:<module>:12 - 這是一條普通訊息
當連續兩次呼叫 add 函式時,loguru 會將新的日誌處理器新增到處理器列表中,而不是覆蓋之前的處理器。這意味著所有新增的處理器都會接收到日誌訊息,並且按照它們被新增的順序來處理這些訊息。
from loguru import logger
logger.add(sink="myapp1.log", level="INFO")
logger.add(sink="myapp2.log", level="INFO")
# 會同時存入所有add新增日誌處理器
logger.info("這是一條普通訊息,存入myapp2")
如果想刪除所有已新增的日誌處理器,loguru執行使用 logger.remove()方法不帶任何引數來移除所有日誌處理器。
from loguru import logger
import sys
# 移除所有日誌處理器(包括終端輸出)
logger.remove()
logger.add(sink="myapp3.log", level="INFO", format="{time:HH:mm:ss} | {message}| {level}")
logger.debug("這是一條除錯資訊存入myapp3")
logger.info("這是一條普通訊息存入myapp3")
注意呼叫logger.remove()之後的所有日誌將不會被記錄,因為沒有處理器了。
from loguru import logger
# 移除所有日誌處理器(包括終端輸出)
logger.remove()
# 沒有輸出
logger.info("這是一條普通訊息存入myapp3")
如果希望移除某些日誌處理器,而不是從所有日誌器中移除,程式碼如下:
from loguru import logger
# 移除預設終端logger,如果終端存在。
# logger.remove(0)
# 新增多個檔案處理器,enqueu設定非同步日誌記錄
handler1 = logger.add("myapp1.log", enqueue=True)
print(handler1) # handler_id是移除的處理器的唯一識別符號
handler2 = logger.add("myapp2.log")
# 記錄一些日誌
logger.info("這些資訊會被記錄到兩個檔案中")
# 移除特定的檔案處理器
logger.remove(handler1)
# 現在只有myapp2.log 會記錄日誌
logger.info("這條資訊只會記錄在myapp2.log 中")
如果想將日誌輸出到日誌臺,程式碼如下:
from loguru import logger
import sys
logger.remove() # 移除預設輸出
# 新增一個日誌處理器,輸出到控制檯,使用自定義格式
logger.add(
sink=sys.stdout,
level="DEBUG",
# green表示顏色
format="<green>{time:HH:mm}</green> <level>{message}</level>"
)
# 注意終端顯示會同步顯示
logger.debug("這是一條除錯資訊")
logger.info("這是一條普通訊息")
時間自定義
可以使用datatime庫來自定義日誌時間格式。
from datetime import datetime
from loguru import logger
# 自定義時間格式
# time_format = "%Y-%m-%d %H:%M:%S,%f" # 包括微秒
time_format = "%H:%M:%S,%f" # 包括微秒但不含年月日
# 定義日誌格式,使用 datetime.now().strftime() 來格式化時間
log_format = "{time:" + time_format + "} - {level} - {message}"
logger.add("myapp.log", format=log_format, level="DEBUG")
# 記錄一條日誌
logger.debug("這是一個帶有微秒的測試日誌")
日誌輪換
from loguru import logger
# 當檔案大小達到100MB時建立新的日誌檔案,舊檔案保留並重新命名,用於防止單個日誌檔案變得過大。
logger.add("file_1.log", rotation="100 MB")
# 每天中午12時建立新的日誌檔案,舊檔案保留並重新命名
logger.add("file_2.log", rotation="12:00")
# 當日志檔案存在超過一週時建立新的日誌檔案,舊檔案保留並重新命名
logger.add("file_3.log", rotation="1 week")
# 設定日誌檔案保留10天
logger.add("file_4.log", retention="10 days")
# 當檔案大小達到100MB時建立新的日誌檔案,舊檔案保留壓縮為zip檔案
logger.add('file_{time}.log', rotation="100 MB", compression='zip')
1.3 進階使用
異常捕獲
@logger.catch裝飾器可以用來裝飾my_function函式,並將這些異常資訊記錄到日誌中。
from loguru import logger
logger.add(sink='myapp.log')
@logger.catch
def my_function(x, y):
return x / y
res = my_function(0,0)
過濾
使用loguru庫進行Python日誌記錄時,可以透過自定義的filter函式來篩選並記錄特定的日誌資訊。此函式接收一個記錄物件作為引數,根據日誌訊息內容(message)、級別(level)或其他日誌屬性,返回布林值以決定是否記錄該條日誌。如果函式返回True,則日誌被記錄;若返回False,則忽略該日誌。
from loguru import logger
# 定義一個過濾器函式
def my_filter(record):
# 只記錄包含 "第一" 的日誌
return "第一" in record["message"]
# 使用過濾器
logger.add("myapp.log", filter=my_filter)
# 記錄一些日誌
logger.info("第一個記錄")
logger.info("第二個記錄")
此外可以結合bind方法進行過濾,bind方法用於向日志記錄器新增額外的上下文資訊。這些資訊將被包含在每條日誌訊息中,但不會改變日誌訊息本身。如下所示:
from loguru import logger
def filter_user(record):
return record["extra"].get("user") =="A"
logger.add("myapp.log", filter=filter_user)
# 繫結user
logger.bind(user="A").info("來自A")
logger.bind(user="B").info("來自B")
2 參考
- loguru
- loguru-doc
- Python日誌記錄庫logging總結
- Python日誌庫Loguru教程