zoukankan      html  css  js  c++  java
  • Python logging模块异步线程写日志实现过程解析

    通过logging模块,重写一个logging2模块,独立开启线程,将待写的日志信息异步放入队列,做到日志输出不影响主流程性能,环境python3.8
    logging2.py
    importos
    importthreading
    importqueue
    importtime
    importdatetime
    importlogging
    fromlogging.handlers importRotatingFileHandler
     
    classlogging2(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)
     
    iflogLevel =='DEBUG':
    self.logger.setLevel(level =logging.DEBUG)
    self.rHandler.setLevel(logging.DEBUG)
    self.console.setLevel(logging.DEBUG)
    eliflogLevel =='INFO':
    self.logger.setLevel(level =logging.INFO)
    self.rHandler.setLevel(logging.INFO)
    self.console.setLevel(logging.INFO)
    eliflogLevel =='WARNING':
    self.logger.setLevel(level =logging.WARN)
    self.rHandler.setLevel(logging.WARN)
    self.console.setLevel(logging.WARN)
    eliflogLevel =='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)
     
    #如果跨天了,则重新生成新的文件名
    defreSetLog(self):
    AdtTemp =datetime.datetime.now().strftime('%Y%m%d')
    #比较新的时间
    ifAdtTemp ==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
     
    defrun(self):
    print("开启日志线程:"+self.name)
    i =0
    whileTrue:
    #data = "queue test data"
    #debug(data)
    #print("Queuesize: %s" % (logging2.AQueue.qsize()))
    self.reSetLog()
    iflogging2.AQueue.empty() ==False:
    #从队列获取日志消息
    data =logging2.AQueue.get()
    #解析日志消息,格式:日志级别,内容
    level =list(data.keys())[0]
    content =data.get(level)
    #把内容按分隔符|解析成list传入参数
    lstContent =list(content.split('|'))
    iflevel =='DEBUG':
    self.logger.debug(*lstContent)
    eliflevel =='INFO':
    self.logger.info(*lstContent)
    eliflevel =='WARNING':
    self.logger.warn(*lstContent)
    eliflevel =='ERROR':
    self.logger.error(*lstContent)
    else:
    time.sleep(0.5)
     
    print("退出线程:"+self.name)
     
    defdebug(*content):
    logMsg =""
    #传入多个参数用竖线分隔符分开
    fori inrange(len(content)):
    ifi ==len(content)-1:
    logMsg +=content[i]
    else:
    logMsg +=content[i]+"|"
    logging2.AQueue.put({'DEBUG':logMsg})
     
    definfo(*content):
    logMsg =""
    fori inrange(len(content)):
    ifi ==len(content)-1:
    logMsg +=content[i]
    else:
    logMsg +=content[i]+"|"
    logging2.AQueue.put({'INFO':logMsg})
     
    defwarn(*content):
    logMsg =""
    fori inrange(len(content)):
    ifi ==len(content)-1:
    logMsg +=content[i]
    else:
    logMsg +=content[i]+"|"
    logging2.AQueue.put({'WARNING':logMsg})
     
    deferror(*content):
    logMsg =""
    fori inrange(len(content)):
    ifi ==len(content)-1:
    logMsg +=content[i]
    else:
    logMsg +=content[i]+"|"
    logging2.AQueue.put({'ERROR':logMsg})
     
    definit(module, level):
    # 创建新线程
    thread1 =logging2(1, "Thread-log", module, level)
    # 开启新线程
    thread1.start()
    # thread1.join()
    测试桩logMain.py
    importsys
    importos
    importtime
    importthreading
     
    if__name__ =='__main__':
    importlogging2
    logging2.init("logMain", "DEBUG")
     
    teststr ="22222"
     
    whileTrue:
    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
    文件内容如下:
     
     
    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
  • 相关阅读:
    基于Text-CNN模型的中文文本分类实战 流川枫 发表于AI星球订阅
    SQL Server 定时执行SQL语句的方法
    linq 根据指定条件返回集合中不重复的元素
    asp.net mvc ChildActionOnly 和ActionName的用法
    C# 让枚举返回字符串
    EF中使用SQL语句或存储过程
    Sql Server系列:视图
    C# 获取web.config配置文件
    C# 在EF中直接运行SQL命令
    c# mvc 获取 HtmlHelper 表达式值和时间格式化 去边框
  • 原文地址:https://www.cnblogs.com/nanhe/p/13508889.html
Copyright © 2011-2022 走看看