Python logging模块异步线程写日志实现过程解析
时间:2022-07-27
本文章向大家介绍Python logging模块异步线程写日志实现过程解析,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
通过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
文件内容如下:
以上就是本文的全部内容,希望对大家的学习有所帮助。
- 《Spark MLlib 机器学习实战》1——读后总结
- angularjs自定义指令实现分页插件
- A+B for Input-Output Practice (V)
- 机器学习——相似度算法汇总
- 白话推荐系统——从原理到实践,还有福利赠送!
- 基于Spring Boot的Logback日志轮转配置
- Java程序员的日常—— Spring Boot单元测试
- Windows下TensorFlow安装指南(图文版)
- 20120918-双向链表类定义《数据结构与算法分析》
- 20120918-LIST类定义《数据结构与算法分析》
- Scala入门学习笔记四--List使用
- 20120918-向量实现《数据结构与算法分析》
- hadoop 1.x环境搭建
- JavaScript二维码生成——qrcode.js
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Tidyverse补充
- 抖音关键词热度搜索小程序(附源码)
- python自定义函数基础
- Python-科学计算-pandas-13-列名/删除列/替换nan
- python小程序,45行代码实现可切换版代码雨(附源码)
- R海拾遗-stringr
- stringr2
- Kubernetes 无状态应用的一般特征
- 一段简单的代码,能让所有GIF图实现时光倒流
- 你喜欢的女主播颜值多少分,今天带你测试虎牙直播女主播的颜值
- (译)kubectl 的奇技淫巧
- Python实现主播人气排行榜,带你发现人气王
- (译)Kubernetes:移除 CPU 限制,服务运行更快
- python_不误正业之贪吃蛇
- 如何让你在众多二手车中挑中满意的?python帮你实现(附源码)