python logging模塊主要是python提供的通用日志系統,使用的方法其實挺簡單的,這塊就不多介紹。下面主要會講到在使用python logging模塊的時候,涉及到多個python文件的調用,而每個文件設置了對應的logging方式不同,可能會產生的令人困惑的現象。
下面以自己在開發的時候遇到的問題作為敘述的背景:
有三個python模塊A、B、C。主模塊A會import B和C模塊,主模塊有對應的logging方式,
A使用logging的模塊的方式為:
import loggingimport logging.handlersdef CreateLogger(logFile = 'batch'): handler = logging.handlers.RotatingFileHandler(str(logFile) + '.LOG', maxBytes = 1024 * 1024 * 500, backupCount = 5) fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s' formatter = logging.Formatter(fmt) handler.setFormatter(formatter) logger = logging.getLogger(str(logFile)) logger.addHandler(handler) logger.setLevel(logging.INFO) return loggersLogger = CreateLogger()
其實A模塊使用logging的方式很簡單,創建一個RotatingFileHandler,通過RotatingFileHandler回滾logging的方式來控制LOG文件的個數和每個LOG文件的上限大小。并創建一個Formatter對象來設置LOG文件的格式。在程序中使用這種方式產生的logging對象來打LOG,很顯然使用這種方式的話,LOG都會打印到對應的LOG文件中去。
B使用logging模塊的方式為
def GetLogger(testName): logger = logging.getLogger(testName) logger.setLevel(logging.INFO) hdlr = logging.FileHandler(testName + '.LOG') hdlr.setLevel(logging.INFO) formatter = logging.Formatter("[%(asctime)s]/t[%(levelname)s]/t[%(thread)d]/t[%(pathname)s:%(lineno)d]/t%(message)s") hdlr.setFormatter(formatter) logger.addHandler(hdlr) return loggerlogger = GetLogger('OK') def SetLogger(log): global logger logger = log
B模塊默認logging的方式跟A差不多,只是B選擇logging的方式是往一個LOG文件中打LOG。A其實在實際使用B模塊對應的函數和類的時候并沒有直接用B的logging方式,而是對B logging進行了一個重定向,這個可以從SetLogger函數的作用可以函數。A直接會把已經logging對象傳給B,這樣B也可以和A共享同一個logging對象,并把LOG打到A設定的文件中。這對于一個主模塊調用多個子模塊的邏輯、而且每個子模塊都有對應的logging使用方式、打到不同文件中進行統一還是挺有好處的,這樣可以有效的控制總的LOG文件大小和數量。
但是沒有注意C模塊,然后發現的情況是,A程序在運行過程中會把A、B模塊的LOG信息直接打到屏幕上,而且LOG文件中也有對應的LOG。這些挺讓人困惑的,把對B模塊的調用注釋掉,依然會發現有A的LOG直接打到屏幕上。但是把A程序中設置logging對象的那段代碼單獨拿出來,一切都正常。
根據當時的情景,只能懷疑是C模塊中有什么設置,會導致A、B模塊打LOG的方式有些轉變。后來意識到,C模塊中并沒有設置logging的對象,而是直接使用logging.info去打LOG。把這部分的邏輯注釋掉,發現A、B打LOG的方式又恢復正常,再也不會往屏幕上打LOG。
新聞熱點
疑難解答