Python logging模塊異步線程寫日志實現(xiàn)過程解析
通過logging模塊,重寫一個logging2模塊,獨立開啟線程,將待寫的日志信息異步放入隊列,做到日志輸出不影響主流程性能,環(huán)境python3.8
logging2.py
import os
import threading
import queue
import time
import datetime
import logging
from logging.handlers import RotatingFileHandler
class logging2(threading.Thread):
AQueue = queue.Queue(100000)
nPID = os.getpid()
Adt = datetime.datetime.now().strftime('%Y%m%d')
nCount = 1
def __init__(self, threadID, name, module, logLevel):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.module = module
print("set loglevel: [%s]" % (logLevel) )
formatter = logging.Formatter('%(asctime)s|%(name)s|%(process)d|%(levelname)s|%(message)s')
logfile = "log_" + self.module + "_" + str(logging2.nPID) + "_" + str(logging2.Adt) + ".log"
self.logger = logging.getLogger(__name__)
self.rHandler = RotatingFileHandler(logfile, maxBytes = 10*1024*1024, backupCount = 10)
self.rHandler.setFormatter(formatter)
self.console = logging.StreamHandler()
self.console.setFormatter(formatter)
if logLevel == 'DEBUG' :
self.logger.setLevel(level = logging.DEBUG)
self.rHandler.setLevel(logging.DEBUG)
self.console.setLevel(logging.DEBUG)
elif logLevel == 'INFO' :
self.logger.setLevel(level = logging.INFO)
self.rHandler.setLevel(logging.INFO)
self.console.setLevel(logging.INFO)
elif logLevel == 'WARNING' :
self.logger.setLevel(level = logging.WARN)
self.rHandler.setLevel(logging.WARN)
self.console.setLevel(logging.WARN)
elif logLevel == 'ERROR' :
self.logger.setLevel(level = logging.ERROR)
self.rHandler.setLevel(logging.ERROR)
self.console.setLevel(logging.ERROR)
self.logger.addHandler(self.rHandler)
self.logger.addHandler(self.console)
#如果跨天了,則重新生成新的文件名
def reSetLog(self):
AdtTemp = datetime.datetime.now().strftime('%Y%m%d')
#比較新的時間
if AdtTemp == logging2.Adt:
return(True)
logging2.Adt = AdtTemp
logfile = "log_" + self.module + "_" + str(logging2.nPID) + "_" + str(AdtTemp) + ".log"
self.rHandler = RotatingFileHandler(logfile, maxBytes = 1*1024, backupCount = 10)
self.logger.addHandler(self.rHandler)
self.logger.addHandler(self.console)
logging2.nCount += 1
def run(self):
print ("開啟日志線程:" + self.name)
i = 0
while True:
#data = "queue test data"
#debug(data)
#print("Queuesize: %s" % (logging2.AQueue.qsize()))
self.reSetLog()
if logging2.AQueue.empty() == False:
#從隊列獲取日志消息
data = logging2.AQueue.get()
#解析日志消息,格式:日志級別,內(nèi)容
level = list(data.keys())[0]
content = data.get(level)
#把內(nèi)容按分隔符|解析成list傳入?yún)?shù)
lstContent = list(content.split('|'))
if level == 'DEBUG' :
self.logger.debug(*lstContent)
elif level == 'INFO' :
self.logger.info(*lstContent)
elif level == 'WARNING' :
self.logger.warn(*lstContent)
elif level == 'ERROR' :
self.logger.error(*lstContent)
else:
time.sleep(0.5)
print ("退出線程:" + self.name)
def debug(*content):
logMsg = ""
#傳入多個參數(shù)用豎線分隔符分開
for i in range(len(content)):
if i == len(content)-1:
logMsg += content[i]
else:
logMsg += content[i]+"|"
logging2.AQueue.put({'DEBUG':logMsg})
def info(*content):
logMsg = ""
for i in range(len(content)):
if i == len(content)-1:
logMsg += content[i]
else:
logMsg += content[i]+"|"
logging2.AQueue.put({'INFO':logMsg})
def warn(*content):
logMsg = ""
for i in range(len(content)):
if i == len(content)-1:
logMsg += content[i]
else:
logMsg += content[i]+"|"
logging2.AQueue.put({'WARNING':logMsg})
def error(*content):
logMsg = ""
for i in range(len(content)):
if i == len(content)-1:
logMsg += content[i]
else:
logMsg += content[i]+"|"
logging2.AQueue.put({'ERROR':logMsg})
def init(module, level):
# 創(chuàng)建新線程
thread1 = logging2(1, "Thread-log", module, level)
# 開啟新線程
thread1.start()
# thread1.join()
測試樁logMain.py
import sys
import os
import time
import threading
if __name__ == '__main__':
import logging2
logging2.init("logMain", "DEBUG")
teststr = "22222"
while True:
logging2.debug('this is a debug log test [%s] ', teststr)
logging2.info('this is a info log test [%s] [%s]', teststr, teststr)
logging2.warn('this is a warn log test')
logging2.error('this is a error log test')
#time.sleep(0.1)
print(threading.enumerate())
print('press ctrl_c to exit')
測試結(jié)果
生成日志文件:
-rw-rw-r--. 1 zxl zxl 10152463 6月 24 17:52 log_logMain_57554_20200624.log
文件內(nèi)容如下:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python解決pip install時出現(xiàn)的Could not fetch URL問題
這篇文章主要介紹了Python解決pip install時出現(xiàn)的Could not fetch URL問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-08-08
opencv+圖像處理(Image Processing in OpenCV)
這篇文章主要介紹了opencv+圖像處理(Image Processing in OpenCV) 4-0改變顏色空間,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
Python使用requests模塊發(fā)送http請求的方法介紹
Python?Requests是一個?HTTP?庫,它允許我們向?Web?服務(wù)器發(fā)送??HTTP?請求,并獲取響應(yīng)結(jié)果,本文將會詳細介紹Python?requests模塊如何發(fā)送http請求,文中有相關(guān)的代碼示例,需要的朋友可以參考下2023-06-06
Python使用正則表達式獲取網(wǎng)頁中所需要的信息
這篇文章主要介紹了Python使用正則獲取網(wǎng)頁中所需要的信息的相關(guān)資料,需要的朋友可以參考下2018-01-01
Python爬取OPGG上英雄聯(lián)盟英雄勝率及選取率信息的操作
這篇文章主要介紹了Python爬取OPGG上英雄聯(lián)盟英雄勝率及選取率信息的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
python通過TimedRotatingFileHandler按時間切割日志
這篇文章主要介紹了python通過TimedRotatingFileHandler按時間切割日志的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07

