簡體   English   中英

Python 多處理日志記錄 - 為什么 multiprocessing.get_logger

[英]Python multiprocessing logging - why multiprocessing.get_logger

一段時間以來,我一直在為多處理日志而苦苦掙扎,原因有很多。

我的一個原因是,為什么另一個 get_logger。

當然,我已經看到了這個問題,而且 multiprocessing.get_logger 返回的記錄器似乎做了一些“進程共享鎖”的魔法,使日志處理變得順暢。

所以,今天我查看了 Python 2.7 的多處理代碼(/multiprocessing/util.py),發現這個記錄器只是一個普通的 logging.Logger,幾乎沒有任何魔法。

這是 Python 文檔中的描述,就在 get_logger 函數之前:

一些日志支持是可用的。 但是請注意,日志記錄包不使用進程共享鎖,因此來自不同進程的消息可能(取決於處理程序類型)混淆。

因此,當您使用錯誤的日志處理程序時,甚至 get_logger 記錄器也可能出錯? 我已經使用了一個使用 get_logger 進行日志記錄的程序。 它將日志打印到 StreamHandler 並且(似乎)永遠不會混淆。

現在我的理論是:

  1. multiprocessing.get_logger 根本不做進程共享鎖
  2. StreamHandler 適用於多處理,但 FileHandler 不適用
  3. 這個 get_logger 記錄器的主要目的是跟蹤進程的生命周期,並提供一個易於獲取和隨時可用的記錄器,它已經記錄了進程的名稱/ID 類型的東西

這是問題:

我的理論對嗎?

您如何/為什么/何時使用此 get_logger?

是的,我相信 multiprocessing.get_logger() 不做進程共享鎖是對的 - 正如你所說,文檔甚至說明了這一點。 盡管獲得了所有贊成票,但您鏈接到的問題似乎有缺陷,說明它確實存在(為了使它具有懷疑的好處,它是十多年前寫的 - 所以也許在某一時刻就是這種情況)。

為什么 multiprocessing.get_logger() 存在呢? 文檔說它:

返回多處理使用的記錄器。 如有必要,將創建一個新的。

首次創建時,記錄器具有級別 logging.NOTSET 並且沒有默認處理程序。 默認情況下,發送到此記錄器的消息不會傳播到根記錄器。

即默認情況下,多處理模塊不會產生任何日志輸出,因為它的記錄器的日志級別設置為 NOTSET,因此不會產生任何日志消息。

如果您懷疑您的代碼存在多處理問題,那么缺少日志輸出將無助於調​​試,這就是 multiprocessing.get_logger() 存在的原因 - 它返回使用的記錄器多處理模塊本身,以便您可以覆蓋默認日志記錄配置以從中獲取一些日志並查看它在做什么。

由於您詢問了如何使用 multiprocessing.get_logger(),您可以這樣稱呼它並以通常的方式配置記錄器,例如:

logger = multiprocessing.get_logger()
formatter = logging.Formatter('[%(levelname)s/%(processName)s] %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# now run your multiprocessing code

也就是說,為了方便起見,您實際上可能想使用 multiprocessing.log_to_stderr() 代替 - 根據文檔

此函數執行對 get_logger() 的調用,但除了返回由 get_logger 創建的記錄器之外,它還添加了一個處理程序,該處理程序使用格式'[%(levelname)s/%(processName)s] %(message)s'

即它使您無需自己設置如此多的日志記錄配置,而您只需使用以下命令即可開始調試多處理問題:

logger = multiprocessing.log_to_stderr()
logger.setLevel(logging.INFO)

# now run your multiprocessing code

重申一下,這只是一個正在配置和使用的普通模塊記錄器,即它沒有什么特別的或過程安全的。 它只是讓您看到多處理模塊本身內部發生了什么。

這個答案是不是get_logger明確,但也許你可以使用建議的方法這個帖子 請注意, QueueHandler / QueueListener類可通過logutils包(也可在 PyPI上獲得)用於較早的 Python 版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM