异步写日志
为什么会想到异步写日志?
附件中下载代码:
假设有以下函数
Python代码
def myfunc():
logging.info('log something ....')
#
#do something
#
logging.info('log something agein')
return 2
这个函数在 return 2 之前记录了2次日志。并且必须要等这两条logging写入硬盘中之后才return 2
现在遇到的一个情况就是这个函数返回之前打印了大量了日志,那就加大了调用函数的返回时间。
想在不改变日志量的情况下,让这个函数执行返回的更加快。logging模块是使用纯python代码来实现的,写文件的效率并不高。
如果能用c或者c++重写一个logging模块,那就更好了,哈哈,但目前没这个能力拿c/c++重写。所以就想到了另外个异步开一个线程来记录日志的办法
这里另外写了个日志模块 取名字叫logging2
Python代码
<span style="font-size: small;">def myfunc():
#这里改用了另外写的logging2模块
logging2.info('log something ....')
#
#do something
#
#这里改用了另外写的logging2模块
logging2.info('log something agein')
return 2</span>
logging2模块主要使用到了内置模块Queue 和 threading
logging2.info 将日志信息写如Queue中,然后另外一个线程不断的从Queue中取出日志,最终打印到硬盘中。
logging2实际上是操作Queue,也就是与内存在进行交互的。
而logging是与硬盘来进行交互的。所以对与函数myfunc的调用来说,logging2要比logging快。这也就达到了我的目的。
至于logging2使用另外一个线程来对硬盘写日志,需要的增加的开销就是:所在进程多一个线程就占用多一些内存,还有cpu占用率会多一些。
附件中下载代码:
代码例子:
example.py
Python代码
#coding=gbk
import sys
import os
import time
import threading
#对logging模块中logger进行的一些封装,实现按照日志按照每天一个文件 或 指定每个日志文件多大尺寸
import LogUtil
_APP_ID_ = 'logging2_test'
############################################################
if __name__ == '__main__':
import logging2 #现在就导入logging2文件
LogUtil.addTimedRotatingFileHandler(
'%s.log' % ( _APP_ID_),
logLevel = 'DEBUG',
)
#注意
logging2.init() #需要多加上这一步, 只需要初始化一次
while 1:
time.sleep(3)
logging2.debug('ddd') #现在就来使用logging2来异步记录日志
logging2.error('testerror')
logging2.info('testerror')
logging2.warning('testerror')
print threading.enumerate()
print 'press ctrl_c to exit'
</span>
logging2.py
Python代码
#coding=gbk
import threading
from Queue import Queue
import logging as log_my
class logging2(threading.Thread):
A_Queue = Queue() #用来存放日志的队列
def __init__(self):
threading.Thread.__init__(self) #初始化父类的构造函数
self.name = 'logging2'
def run(self):
while 1:
data = logging2.A_Queue.get()
print 'datafromqueue',data
loglevel = data.keys()[0]
content = data.values()[0]
getattr(log_my,loglevel)(content)
def info(content):
logging2.A_Queue.put({'info':content})
def error(content):
logging2.A_Queue.put({'error':content})
def debug(content):
logging2.A_Queue.put({'debug':content})
def warning(content):
logging2.A_Queue.put({'warning':content})
def init():
'''''
开启写日志的线程
'''
cc = logging2()
cc.setDaemon(True)
cc.start()
补充:Web开发 , Python ,