簡體   English   中英

使用多個模塊的python日志記錄並寫入文件和RotatingFileHandler

[英]Using python logging from multiple modules with writing to a file and RotatingFileHandler

我正在使用以下模塊在模塊中記錄事件。 我稱其為:

模塊1

from tools.debug_logger import debug_logger
self.logger = debug_logger().start_logger('module1')
self.logger.debug("Top left corner found")

模塊2:

from tools.debug_logger import debug_logger
self.logger = debug_logger().start_logger('module2')
self.logger.debug("Top left corner found")

這里是文件/tools/debug_logger.py

import logging, logging.handlers
import sys
class debug_logger(object):
    def start_logger(self,name):
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        if not len(logger.handlers):
            fh = logging.handlers.RotatingFileHandler('log/pokerprogram.log', maxBytes=1000000, backupCount=10)
            fh.setLevel(logging.DEBUG)
            fh2 = logging.handlers.RotatingFileHandler('log/pokerprogram_info_only.log', maxBytes=1000000, backupCount=5)
            fh2.setLevel(logging.INFO)
            er = logging.handlers.RotatingFileHandler('log/errors.log', maxBytes=2000000, backupCount=2)
            er.setLevel(logging.WARNING)
            ch = logging.StreamHandler(sys.stdout)
            ch.setLevel(1)
            fh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
            fh2.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
            er.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
            ch.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s'))
            logger.addHandler(fh)
            logger.addHandler(fh2)
            logger.addHandler(ch)
            logger.addHandler(er)
        return logger

一切正常,我獲得了各個級別的日志文件,但是當調用RotatingFileHandler時,有時會出錯。 好像各種實例都希望同時進行輪換,即使我非常確定也不應該發生這種情況,因為我確保只有一個處理程序, if not len(logger.handlers)建議使用if not len(logger.handlers)按照此處的建議進行操作: 復制使用Python日志記錄模塊時的日志輸出

任何建議在輪換期間可能導致此文件訪問沖突的建議都將受到贊賞。

PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\Nicolas\\Dropbox\\PythonProjects\\Poker\\log\\pokerprogram.log' -> 'C:\\Users\\Nicolas\\Dropbox\\PythonProjects\\Poker\\log\\pokerprogram.log.1'

我相信會發生權限錯誤,因為發生輪換時,其他模塊仍在寫入文件。

當我寫入文件並使用此RotatingFileHandler時,從多個模塊進行日志記錄的最佳方法是什么? 有沒有最佳做法?

我相信您輸入的日志記錄設置有誤。 推薦的設置日志記錄的方法是不要在模塊中定義任何處理程序或日志記錄級別,而應在主文件中定義所有配置。

例如在module1.py

import logging

logger = logging.getLogger(__name__)

# use logger.info/logger.debug etc.

module2.py您輸入了完全相同的代碼:

import logging

logger = logging.getLogger(__name__)

# use logger.info/logger.debug etc.

請注意, __name__是模塊名稱,因此它將類似於package.module1package.module2 使用虛線名稱會自動創建記錄器的層次結構,因此這就是為什么習慣使用模塊的__name__來獲取記錄器的原因。

不需要module1module2包含與日志記錄有關的任何其他內容。 他們應該決定在哪里日志輸出變為或其水平,因為這一點是誰啟動應用程序應該控制。 因此,最好在主可執行文件中進行處理。

現在,在主可執行文件中定義處理程序:

import logging, logging.handlers

fh = logging.handlers.RotatingFileHandler('log/pokerprogram.log', maxBytes=1000000, backupCount=10)
fh.setLevel(logging.DEBUG)
fh2 = logging.handlers.RotatingFileHandler('log/pokerprogram_info_only.log', maxBytes=1000000, backupCount=5)
fh2.setLevel(logging.INFO)
er = logging.handlers.RotatingFileHandler('log/errors.log', maxBytes=2000000, backupCount=2)
er.setLevel(logging.WARNING)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(1)
fh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
fh2.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
er.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
ch.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s'))

最后,您只需將處理程序添加到根記錄器中 ,並將根記錄器的級別設置為處理程序中的最低級別:

root = logging.getLogger()
root.setLevel(logging.DEBUG)
# alternatively:
# root.setLevel(min([fh.level, fh2.level, ch.level, er.level])

root.addHandler(fh)
root.addHandler(fh2)
root.addHandler(ch)
root.addHandler(er)

這是由於記錄器的分層性質而起作用的。 調用module1.logger.debug ,如果記錄器沒有處理程序,它將日志記錄傳遞給其父記錄器,父記錄器將繼續這樣做,直到根記錄器最終使用其處理程序來處理日志記錄。

還必須設置根記錄器級別,因為它默認為WARNING ,而其他記錄器默認為NOTSET (這將導致前面提到的委托)。

或者,您將相同的處理程序顯式添加到兩個模塊記錄器中:

from <package> import module1, module2

module1.logger.setLevel(logging.DEBUG)
module2.logger.setLevel(logging.DEBUG)

module1.logger.addHandler(fh)
module2.logger.addHandler(fh)
module1.logger.addHandler(fh2)
module2.logger.addHandler(fh2)
module1.logger.addHandler(ch)
module2.logger.addHandler(ch)
module1.logger.addHandler(er)
module2.logger.addHandler(er)

將相同的處理程序對象添加到多個記錄器中沒有害處。 這樣可以確保處理程序不會嘗試同時旋轉文件。

暫無
暫無

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

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