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使用pyqt写带界面工具的示例代码
Oct 23 Python
《Python学习手册》学习总结
Jan 17 Python
Python中的默认参数实例分析
Jan 29 Python
安装python时MySQLdb报错的问题描述及解决方法
Mar 20 Python
Python 3.6 读取并操作文件内容的实例
Apr 23 Python
Django框架模板注入操作示例【变量传递到模板】
Dec 19 Python
在python下使用tensorflow判断是否存在文件夹的实例
Jun 10 Python
python 如何去除字符串头尾的多余符号
Nov 19 Python
np.newaxis 实现为 numpy.ndarray(多维数组)增加一个轴
Nov 30 Python
PyTorch中的C++扩展实现
Apr 02 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
May 25 Python
Python 里最强的地图绘制神器
Mar 01 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
利用ThinkPHP内置的ThinkAjax实现异步传输技术的实现方法
2011/12/19 PHP
PHP使用GIFEncoder类生成gif动态滚动字幕
2014/07/01 PHP
PHP isset()与empty()的使用区别详解
2017/02/10 PHP
ThinkPHP防止重复提交表单的方法实例分析
2018/05/10 PHP
thinkPHP和onethink微信支付插件分享
2019/08/11 PHP
laravel高级的Join语法详解以及使用Join多个条件
2019/10/16 PHP
计算新浪Weibo消息长度(还可以输入119字)
2013/07/02 Javascript
利用jquery操作Radio方法小结
2014/10/20 Javascript
javascript实现类似超链接的效果
2014/12/26 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
2017/03/07 Javascript
JavaScript制作简单的框选图表
2017/05/15 Javascript
vue2.0 可折叠列表 v-for循环展示的实例
2018/09/07 Javascript
Vue2 添加数据可视化支持的方法步骤
2019/01/02 Javascript
详解vue2.6插槽更新v-slot用法总结
2019/03/09 Javascript
原生js实现随机点餐效果
2019/12/10 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
JavaScript中常用的3种弹出提示框(alert、confirm、prompt)
2020/11/10 Javascript
基于Python的身份证号码自动生成程序
2014/08/15 Python
python模拟Django框架实例
2016/05/17 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
Python3实现的简单验证码识别功能示例
2018/05/02 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
2018/12/05 Python
对python中字典keys,values,items的使用详解
2019/02/03 Python
Python 序列化和反序列化库 MarshMallow 的用法实例代码
2020/02/25 Python
python中resample函数实现重采样和降采样代码
2020/02/25 Python
将 Ubuntu 16 和 18 上的 python 升级到最新 python3.8 的方法教程
2020/03/11 Python
python的Jenkins接口调用方式
2020/05/12 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
python温度转换华氏温度实现代码
2020/12/06 Python
html5 冒号分隔符对齐的实现
2019/07/31 HTML / CSS
Bjorn Borg官方网上商店:国际运动时尚品牌
2016/08/27 全球购物
自荐书4要点
2014/01/25 职场文书
运动会稿件200字
2014/02/07 职场文书
致400米运动员广播稿
2014/02/07 职场文书
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技