1. 程式人生 > 其它 >Python 中 logging 日誌模組在多程序環境下的使用

Python 中 logging 日誌模組在多程序環境下的使用

技術標籤:pythonlinux多程序logging記憶體洩漏

最近爬蟲遇到了一個控制代碼洩露的問題

大概問題是多程序往同一個日誌檔案中寫日誌,由於我設定了日誌檔案大小,所以會面臨不同程序對同一個檔案進行讀寫
控制代碼洩漏導致磁碟空間無法釋放,機器的磁碟被佔滿
在此記錄一下解決辦法

引自https://www.cnblogs.com/luchuangao/p/logging.html

多程序環境下logging的使用
按照官方文件的介紹,logging 是執行緒安全的,也就是說,在一個程序內的多個執行緒同時往同一個檔案寫日誌是安全的。但是(對,這裡有個但是)多個程序往同一個檔案寫日誌不是安全的。官方的說法是這樣的:

Because there is no standard way to serialize access to a single file across multiple processes in Python. If you need to log to a single file from multiple processes, one way of doing this is to have all the processes log to a SocketHandler, and have a separate process which implements a socket server which reads from the socket and logs to file. (If you prefer, you can dedicate one thread in one of the existing processes to perform this function.)

有的人會說,那我不用多程序不就可以了。但是 Python 有一個 GIL 的大鎖(關於 GIL 的糾葛可以看這裡),使用多執行緒是沒法利用到多核 CPU 的,大部分情況下會改用多程序來利用多核 CPU,因此我們還是繞不開不開多程序下日誌的問題。

為了解決這個問題,可以使用 ConcurrentLogHandler,ConcurrentLogHandler 可以在多程序環境下安全的將日誌寫入到同一個檔案,並且可以在日誌檔案達到特定大小時,分割日誌檔案。在預設的 logging 模組中,有個 TimedRotatingFileHandler 類,可以按時間分割日誌檔案,可惜 ConcurrentLogHandler 不支援這種按時間分割日誌檔案的方式。

先安裝一下ConcurrentLogHandler
在這裡插入圖片描述
用法如下:

from cloghandler import ConcurrentRotatingFileHandler

LOG_FILE_PATH = '日誌路徑'

#檔案大小和檔案數量我設成了20M和10個,可以根據自己的需要更改
handler = ConcurrentRotatingFileHandler(LOG_FILE_PATH, maxBytes=1024 * 1024 * 20, backupCount=10)

然後在需要寫日誌的檔案中

import logging
from settings import handler
logger = logging.getLogger(__name__)
logger.addHandler(handler)

執行後可以發現,會自動建立一個.lock檔案,通過鎖的方式來安全的寫日誌檔案。