首頁  >  文章  >  後端開發  >  詳解Python中logging日誌模組在多進程環境下的使用

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

高洛峰
高洛峰原創
2017-02-14 13:51:081911瀏覽

許多應用程式中都會有日誌模組,用於記錄系統在運行過程中的一些關鍵信息,以便於對系統的運行狀況進行追蹤。這篇文章給大家主要介紹了在Python中logging日誌模組在多進程環境下的使用,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

相信每位程式設計師應該都知道,在使用Python 來寫後台任務時,時常需要使用輸出日誌來記錄程式運行的狀態,並在發生錯誤時將錯誤的詳細資訊保存下來,以別調試和分析。 Python 的 logging 模組就是這種情況下的好幫手。

logging 模組可以指定日誌的級別,DEBUG、INFO、WARNING、ERROR、CRITICAL,例如可以在開發和調試時,把 DEBUG 以上級別的日誌都輸出,而在生產環境下,只輸出 INFO 級別。 (如果不特別指定,預設等級是 warning)

logging 也可以指定輸出到命令列或文件,也可以按時間或大小分割記錄檔。

關於 logging 的詳細使用,這裡就不再細說,可以參考官方文檔,或這裡的介紹。

logging 的配置

通常情況下,我們需要將日誌保存到文件中,並期望能自動分割文件,避免日誌文件太大。下面給了一個 logging 的設定範例。

import logging.config
 
logging.config.dictConfig({
 'version': 1,
 'disable_existing_loggers': True,
 'formatters': {
  'verbose': {
   'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
   'datefmt': "%Y-%m-%d %H:%M:%S"
  },
  'simple': {
   'format': '%(levelname)s %(message)s'
  },
 },
 'handlers': {
  'null': {
   'level': 'DEBUG',
   'class': 'logging.NullHandler',
  },
  'console': {
   'level': 'DEBUG',
   'class': 'logging.StreamHandler',
   'formatter': 'verbose'
  },
  'file': {
   'level': 'DEBUG',
   'class': 'logging.RotatingFileHandler',
   # 当达到10MB时分割日志
   'maxBytes': 1024 * 1024 * 10,
   # 最多保留50份文件
   'backupCount': 50,
   # If delay is true,
   # then file opening is deferred until the first call to emit().
   'delay': True,
   'filename': 'logs/mysite.log',
   'formatter': 'verbose'
  }
 },
 'loggers': {
  '': {
   'handlers': ['file'],
   'level': 'info',
  },
 }
})

我們在一個模組內,就可以這樣使用來記錄日誌

import logging
logger = logging.getLogger(__name__)
 
if __name__ == '__main__':
 logger.info('log info')

多進程環境下的使用

logging.config.dictConfig({
 ...
 'handlers': {
  'file': {
   'level': 'DEBUG',
   # 如果没有使用并发的日志处理类,在多实例的情况下日志会出现缺失
   'class': 'cloghandler.ConcurrentRotatingFileHandler',
   # 当达到10MB时分割日志
   'maxBytes': 1024 * 1024 * 10,
   # 最多保留50份文件
   'backupCount': 50,
   # If delay is true,
   # then file opening is deferred until the first call to emit().
   'delay': True,
   'filename': 'logs/mysite.log',
   'formatter': 'verbose'
  }
 },
 ...
})

多進程環境下的使用

,在一個行程內的多個執行緒同時往同一個檔案寫日誌是安全的。但是(對,這裡有個但是)多個行程往同一個檔案寫日誌不是安全的。官方的說法是這樣的:

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 multiplecesses, one way of doing log to a single file from multiplecesses, one way of doing log 是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 prothis to experisting prothis.

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

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

重新修改下 handlers 中的 class。

rrreee

運行後可以發現,會自動創建一個.lock文件,通過鎖的方式來安全的寫日誌文件。 🎜🎜更多詳解Python中logging日誌模組在多進程環境下的使用相關文章請關注PHP中文網! 🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn