Python logging模块异步线程写日志实现过程解析


Posted in Python onJune 30, 2020

通过logging模块,重写一个logging2模块,独立开启线程,将待写的日志信息异步放入队列,做到日志输出不影响主流程性能,环境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()
        #解析日志消息,格式:日志级别,内容
        level = list(data.keys())[0]
        content = data.get(level)
        #把内容按分隔符|解析成list传入参数
        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 = ""
  #传入多个参数用竖线分隔符分开
  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):
  # 创建新线程
  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')

测试结果

生成日志文件:

-rw-rw-r--. 1 zxl zxl 10152463 6月 24 17:52 log_logMain_57554_20200624.log

文件内容如下:

Python logging模块异步线程写日志实现过程解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python遍历文件夹并删除特定格式文件的示例
Mar 05 Python
python继承和抽象类的实现方法
Jan 14 Python
Python进程间通信用法实例
Jun 04 Python
Python实现文件复制删除
Apr 19 Python
python 请求服务器的实现代码(http请求和https请求)
May 25 Python
python批量修改图片大小的方法
Jul 24 Python
详解用python写网络爬虫-爬取新浪微博评论
May 10 Python
Python之NumPy(axis=0 与axis=1)区分详解
May 27 Python
命令行运行Python脚本时传入参数的三种方式详解
Oct 11 Python
Python3实现个位数字和十位数字对调, 其乘积不变
May 03 Python
Python 爬虫性能相关总结
Aug 03 Python
使用Pytorch实现two-head(多输出)模型的操作
May 28 Python
浅谈多卡服务器下隐藏部分 GPU 和 TensorFlow 的显存使用设置
Jun 30 #Python
Tensorflow中批量读取数据的案列分析及TFRecord文件的打包与读取
Jun 30 #Python
使用Tensorflow-GPU禁用GPU设置(CPU与GPU速度对比)
Jun 30 #Python
keras的backend 设置 tensorflow,theano操作
Jun 30 #Python
浅谈TensorFlow中读取图像数据的三种方式
Jun 30 #Python
python中 _、__、__xx__()区别及使用场景
Jun 30 #Python
Django实现内容缓存实例方法
Jun 30 #Python
You might like
php垃圾代码优化操作代码
2010/08/05 PHP
国外十大最流行的PHP框架排名
2013/07/04 PHP
php序列化函数serialize() 和 unserialize() 与原生函数对比
2015/05/08 PHP
分享一个漂亮的php验证码类
2016/09/29 PHP
php中文乱码问题的终极解决方案汇总
2017/08/01 PHP
PHP基于面向对象封装的分页类示例
2019/03/15 PHP
无阻塞加载脚本分析[全]
2011/01/20 Javascript
JavaScript入门之基本函数详解
2011/10/21 Javascript
flash调用js中的方法,让js传递变量给flash的办法及思路
2013/08/07 Javascript
2014年最火的Node.JS后端框架推荐
2014/10/27 Javascript
教你用javascript实现随机标签云效果_附代码
2016/03/16 Javascript
基于jquery实现ajax无刷新评论
2020/08/19 Javascript
JavaScript之cookie技术详解
2016/11/18 Javascript
详解基于Vue+Koa的pm2配置
2017/10/24 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
2017/12/01 Javascript
详解html-webpack-plugin用法全解
2018/01/22 Javascript
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
2018/05/29 Javascript
layui 数据表格 根据值(1=业务,2=机构)显示中文名称示例
2019/10/26 Javascript
jQuery实现轮播图效果demo
2020/01/11 jQuery
vue 使用微信jssdk,调用微信相册上传图片功能
2020/11/13 Javascript
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
python tensorflow学习之识别单张图片的实现的示例
2018/02/09 Python
使用11行Python代码盗取了室友的U盘内容
2018/10/23 Python
对pandas数据判断是否为NaN值的方法详解
2018/11/06 Python
Python assert语句的简单使用示例
2019/07/28 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
详解python metaclass(元类)
2020/08/13 Python
python在CMD界面读取excel所有数据的示例
2020/09/28 Python
路易威登和香奈儿手袋:LuxeDH
2017/01/12 全球购物
爱尔兰领先的在线体育用品零售商:theGAAstore
2018/04/16 全球购物
LVMH旗下最大的奢侈品网站平台:24S
2020/05/24 全球购物
预备党员表决心书
2014/03/11 职场文书
民主生活会发言材料
2014/10/20 职场文书
《蟋蟀的住宅》教学反思
2016/02/17 职场文书
python使用torch随机初始化参数
2022/03/22 Python