在現今軟體開發環境中,日誌記錄和並發處理是不可或缺的環節。尤其在非同步應用程式中,有效管理日誌訊息更顯重要。本文將探討如何在 Python 非同步環境下,使用內建 logging 模組和第三方函式庫 Loguru 進行日誌記錄,並示範如何捕捉異常、自訂日誌格式、設定日誌輪替與壓縮等技巧。首先,我們會介紹 Python 內建 logging 模組的非同步設定方式,利用 QueueHandler 和 QueueListener 實作非阻塞的日誌寫入,避免影響主程式的執行效能。接著,將探討 Loguru 函式庫的應用,其簡潔的語法和豐富的功能,能大幅簡化日誌處理流程。Loguru 提供了更彈性的日誌格式化選項,以及更便捷的異常捕捉機制,讓開發者能更專注於程式邏輯的開發,而不需花費過多時間在日誌設定上。
此外,文章也將示範 Loguru 如何與終端機顏色整合,讓不同級別的日誌訊息更易於區分,方便開發者快速識別關鍵資訊。同時,也會介紹 Loguru 的日誌輪替和壓縮功能,有效管理日誌檔案大小,避免磁碟空間被大量日誌佔用。最後,文章將提供一些進階的 Loguru 使用技巧,例如設定日誌保留策略,自動刪除過期的日誌檔案,以及如何根據不同需求調整和最佳化 Loguru 的設定。透過本文的介紹,讀者將能瞭解如何在 Python 非同步應用程式中有效地進行日誌記錄,並掌握 Loguru 函式庫的應用技巧,提升日誌管理效率和系統穩定性。
非同步日誌與並發處理
在現代軟體開發中,日誌記錄(logging)和並發處理(concurrency)是兩個至關重要的主題。本篇文章將探討如何在非同步應用程式中實作有效的日誌記錄,並展示如何使用Python的內建日誌模組來處理這些問題。
日誌與並發的基礎
日誌記錄是軟體開發中不可或缺的一部分,它幫助開發者追蹤應用程式的執行狀態,捕捉錯誤並進行除錯。而在非同步應用程式中,日誌記錄的實作會更加複雜,因為需要處理多個任務同時執行的情況。
使用Python內建日誌模組
Python的內建logging模組提供了強大的日誌記錄功能,但預設情況下是同步的。為了適應非同步應用程式的需求,我們需要進行一些調整。
設定日誌記錄
首先,我們來看看如何設定非同步日誌記錄。以下是一個完整的範例:
import asyncio
import logging
import random
from queue import SimpleQueue
from loguru import logger
MESSAGES = ["working", "idling", "sleeping"]
async def setup_logging():
log_queue = SimpleQueue()
root = logging.getLogger()
root.setLevel(logging.DEBUG)
# 建立非阻塞處理器
queue_handler = logging.handlers.QueueHandler(log_queue)
root.addHandler(queue_handler)
# 建立阻塞處理器
file_handler = logging.FileHandler("queued.log")
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
file_handler.setFormatter(formatter)
listener = logging.handlers.QueueListener(log_queue, file_handler)
try:
listener.start()
logger.debug("Async logging started")
while True:
await asyncio.sleep(60)
finally:
logger.debug("Logger is being shut down!")
listener.stop()
#### 內容解密:
在此範例中,我們首先建立了一個簡單佇列(SimpleQueue),然後設定了根日誌器(root logger)的等級為DEBUG。接著,我們建立了一個非阻塞處理器(QueueHandler)並將其新增到根日誌器中。
之後,我們建立了一個阻塞處理器(FileHandler),並設定了一個格式化器(Formatter)來定義日誌訊息的格式。最後,我們將阻塞處理器新增到一個QueueListener例項中,這樣就可以在不阻塞主程式的情況下進行日誌寫入。
#### 任務函式
接下來,我們來看看如何定義一個非同步任務:
```python
async def task(number):
logger.info(f"Starting task #{number}")
await asyncio.sleep(random.randint(1, 5))
msg = random.choice(MESSAGES)
logger.info(f"Task {number} is {msg}")
logger.info(f"Task #{number} is finished")
主函式
最後,我們來看看主函式是如何啟動日誌記錄並執行多個任務的:
async def main():
# 初始化日誌記錄
asyncio.create_task(setup_logging())
await asyncio.sleep(0.1)
logger.info("Main function started")
async with asyncio.TaskGroup() as group:
for t in range(10):
group.create_task(task(t))
logger.info("All work done")
if __name__ == "__main__":
asyncio.run(main())
內容解密:
在主函式中,我們首先初始化了日誌記錄並建立了一個非同步任務來執行setup_logging函式。然後,我們啟動了十個非同步任務來模擬工作流程。最後,當所有任務完成時,我們記錄一條訊息表示所有工作已完成。
使用Loguru簡化日誌記錄
除了Python內建的logging模組外,還有一些第三方函式庫可以簡化日誌記錄。其中最受歡迎的一個就是Loguru。Loguru旨在消除Python標準日誌API中的冗長程式碼。
安裝Loguru
安裝Loguru非常簡單,只需要使用pip命令即可:
python -m pip install loguru
Loguru簡單使用範例
使用Loguru進行日誌記錄非常簡單:
from loguru import logger
logger.debug("Hello from loguru!")
logger.info("Informed from loguru!")
這段程式碼僅需兩行就可以開始進行日誌記錄。預設情況下,Loguru會將日誌訊息輸出到標準輸出(stdout)。
處理例外與終端顏色
Loguru還提供了捕捉例外、終端顏色等功能,使得日誌記錄更加直觀和便捷。
日誌管理:深入 Loguru 的使用
在現代軟體開發中,日誌管理是一個不可或缺的工具。它不僅能幫助開發者追蹤應用程式的執行狀態,還能在問題發生時提供有價值的訊息。Loguru 是一個強大且易於使用的 Python 日誌函式庫,它提供了靈活的日誌處理和格式化功能。以下是 Loguru 的一些核心概念和實際應用。
日誌處理與格式化
Loguru 使用「sink」來處理日誌訊息,這與 Python 的標準 logging 模組中的「handler」有所不同。sink 告訴 Loguru 如何處理和寫入日誌訊息。sink 可以是多種形式,包括檔案物件、檔案路徑、可呼叫物件、非同步協程函式以及內建的 logging.Handler。
為了更好地理解這些概念,讓我們來建立一個新的 Python 檔案 file_formatting.py,並在其中新增一些範例程式碼。
# file_formatting.py
from loguru import logger
fmt = "{time} - {name} - {level} - {message}"
logger.add("formatted.log", format=fmt, level="INFO")
logger.debug("這是一個除錯訊息")
logger.info("這是一則資訊訊息")
內容解密:
- 引入
loguru:首先,我們從loguru模組中匯入logger。 - 定義格式:我們定義了一個格式字串
fmt,這個字串包含了日誌訊息中需要顯示的元素,例如時間、模組名稱、日誌等級和訊息內容。 - 新增日誌 sink:我們使用
logger.add()方法來新增一個新的日誌 sink,這裡我們將日誌寫入到名為formatted.log的檔案中。 - 記錄日誌:最後,我們使用
logger.debug()和logger.info()來記錄不同等級的日誌訊息。
如果你想改變日誌的輸出位置,可以使用 add() 方法來新增新的 sink。注意,這會在現有的 handler 列表中新增一個新的 sink。如果你想移除預設的 sink,可以在呼叫 add() 之前使用 logger.remove()。
日誌格式化
Loguru 提供了豐富的格式化選項,這些選項可以幫助你自定義日誌訊息的外觀。以下是一些常見的格式化指令:
{time}:記錄時間{name}:模組名稱{level}:日誌等級{message}:未格式化的日誌訊息{file}:記錄來自哪個檔案{function}:記錄來自哪個函式{line}:記錄來自哪一行{thread}:記錄來自哪個執行緒
你還可以自定義時間格式。例如,如果你想要只顯示時間而不顯示日期,可以使用 {time:HH:mm:ss}。
捕捉異常
Loguru 提供了一種簡單而強大的方法來捕捉異常。你可以使用 @logger.catch 裝飾器來捕捉函式中的異常。讓我們建立一個新的 Python 檔案 catching_exceptions.py,並新增一些範例程式碼。
# catching_exceptions.py
from loguru import logger
@logger.catch
def silly_function(x, y, z):
return 1 / (x + y + z)
def main():
fmt = "{time:HH:mm:ss} - {name} - {level} - {message}"
logger.add("exception.log", format=fmt, level="INFO")
logger.info("應用程式啟動")
silly_function(0, 0, 0)
logger.info("完成!")
if __name__ == "__main__":
main()
內容解密:
- 引入
loguru:首先,我們從loguru模組中匯入logger。 - 定義函式並新增裝飾器:我們定義了一個名為
silly_function的函式,並使用@logger.catch裝飾器來捕捉異常。 - 主函式:在主函式中,我們定義了一個格式字串並增加了一個新的日誌 sink。接著,我們記錄了一些資訊性日誌訊息並呼叫了可能會引發異常的函式。
- 執行主函式:最後,我們檢查
__name__ == "__main__"以確保主函式在執行時被呼叫。
當你執行這段程式碼時,你會在終端和日誌檔案中看到類別似以下內容:
2024-05-07 14:38:30.258 - __main__ - INFO - 應用程式啟動
2024-05-07 14:38:30.259 - __main__ - ERROR - 在函式 'main' 中捕捉到錯誤:
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
2024-05-07 14:38:30.264 - __main__ - INFO - 完成!
這樣就完成了 Loguru 的基本使用。透過這些範例,你應該能夠更好地理解如何在實際應用中使用 Loguru 進行日誌管理和異常捕捉。
次段落標題(包含「內容解密:」)
接下來玄貓將進一步探討Loguru在不同場景下如何進行多樣性應用以及如何根據需求進行調整與最佳化。
次段落標題(包含「內容解密:」)
玄貓將深度挖掘Loguru之外更多與其相關之技術與框架之應用與整合方式
使用 Loguru 進行日誌記錄
在現代軟體開發中,日誌記錄是一項不可或缺的技能。透過日誌記錄,開發者可以追蹤應用程式的執行狀況,偵錯及最佳化效能。Loguru 是一個強大且易於使用的 Python 日誌記錄函式庫,能夠簡化日誌記錄的過程,並提供豐富的功能來滿足各種需求。
捕捉異常
Loguru 提供了一個簡單且有效的方式來捕捉異常。以下是一個示範如何使用 @logger.catch 來捕捉異常的範例:
from loguru import logger
def silly_function(x, y, z):
return 1 / (x + y + z)
def main():
silly_function(0, 0, 0)
if __name__ == "__main__":
logger.add("debug.log", format="{time} {level} {message}", level="DEBUG")
logger.info("Application starting")
try:
main()
except Exception as e:
logger.exception("An error has occurred")
logger.info("Finished!")
內容解密:
這段程式碼展示瞭如何使用 Loguru 來捕捉異常。首先,定義了一個簡單的函式 silly_function,這個函式會在 x + y + z 為零時引發 ZeroDivisionError。在 main 函式中呼叫 silly_function,並使用 @logger.catch 裝飾器來捕捉可能發生的異常。當異常發生時,Loguru 會自動記錄錯誤訊息及堆積疊追蹤(stack trace)。
###終端機日誌與顏色
Loguru 預設情況下會在終端機中以顏色輸出日誌,這樣可以更容易地區分不同級別的日誌訊息。你也可以自訂日誌格式來新增顏色標籤。
import sys
from loguru import logger
fmt = ("<red>{time}</red> - "
"<yellow>{name}</yellow> - "
"{level} - {message}")
logger.add(sys.stdout, format=fmt, level="DEBUG")
logger.debug("This is a debug message")
logger.info("This is an informational message")
內容解密:
這段程式碼展示瞭如何自訂 Loguru 的日誌格式。首先定義了一個格式字串 fmt,其中使用了 <red> 和 <yellow> 標籤來分別將時間和名稱部分顯示為紅色和黃色。然後將這個格式字串新增到 logger 中,並設定日誌級別為 “DEBUG”。這樣當執行 logger.debug 和 logger.info 時,輸出的日誌訊息會顯示為指定的顏色。
日誌輪轉
Loguru 提供了簡單且靈活的日誌輪轉功能。你只需要在呼叫 add() 方法時指定 rotation 引數即可。以下是幾個示範:
from loguru import logger
fmt = "{time} - {name} - {level} - {message}"
logger.add("rotated.log", format=fmt, level="DEBUG", rotation="50 B")
logger.debug("This is a debug message")
logger.info("This is an informational message")
內容解密:
這段程式碼展示瞭如何使用 Loguru 進行日誌輪轉。首先定義了一個格式字串 fmt,然後將其新增到 logger 中並設定旋轉條件為每 50 位元組進行一次輪轉。當執行 logger.debug 和 logger.info 時,會生成多個日誌檔案,每當檔案大小達到指定限制時會進行輪轉。
日誌壓縮
除了輪轉功能之外,Loguru 還支援對輪轉後的日誌檔案進行壓縮。你可以透過設定 compression 引數來實作這一功能。
from loguru import logger
fmt = "{time} - {name} - {level} - {message}"
logger.add("compressed.log", format=fmt, level="DEBUG", rotation="50 B", compression="zip")
logger.debug("This is a debug message")
logger.info("This is an informational message")
for i in range(10):
logger.info(f"Log message {i}")
內容解密:
這段程式碼展示瞭如何使用 Loguru 對輪轉後的日誌檔案進行壓縮。首先定義了一個格式字串 fmt,然後將其新增到 logger 中並設定旋轉條件和壓縮格式為 “zip”。當執行 logger.debug 和 logger.info 時,會生成多個壓縮後的日誌檔案。
日誌保留
你也可以設定日誌保留策略來自動刪除舊的日誌檔案:
logger.add("file.log", rotation="100 MB", retention="5 days")
內容解密:
這段程式碼展示瞭如何設定 Loguru 的日誌保留策略。透過設定 retention 引數為 “5 days”,Loguru 會自動刪除超過五天未更新的舊日誌檔案。
###結論
Loguru 是一個功能強大且易於使用的 Python 日誌記錄函式庫,它簡化了日誌記錄的過程並提供了豐富的功能來滿足各種需求。無論是捕捉異常、自訂顏色格式還是進行日誌輪轉與壓縮,Loguru 均能輕鬆應對。
推薦進一步學習方向
玄貓推薦您參考 Loguru 的官方檔案以取得更多詳細資訊及進階用法。
https://loguru.readthedocs.io/en/stable/overview.html
透過學習並應用 Loguru 的各種功能,您將能夠更有效地管理和分析應用程式中的日誌記錄,從而提升開發效率及系統穩定性。
此圖示代表如何依照不同需求進行選擇設定:
graph TD;
A[Log Record] --> B[Color Terminal];
A --> C[Exception Catch];
A --> D[Rotation];
A --> E[Compression];
A --> F[Retention];
專案說明:
- Color Terminal:利用顏色增強終端機上日誌讀取體驗。
- Exception Catch:捕捉例外並自動記錄。
- Rotation:根據檔案大小、時間間隔等規則輪替檔案。
- Compression:在輪替檔案時壓縮舊檔案以節省儲存空間。
- Retention:刪除超過特定期限未更新的舊檔案以釋放儲存空間