写一个生成器函数读取日志文件:
def log_data(filename):
from logs.logs_path import LOG_DIR
'''
:param filename: 要读取的日志文件名
'''
fp = open(os.path.join(LOG_DIR, filename), 'rb')
for line in fp.readlines():
try:
line = str(line.decode())
# 使用生成器,这样可以节省内存空间。
except:
continue
yield line
fp.close()
写一个有长度限制的队列,通过list实现
# 封装一个固定长度的队列
class Queue():
def __init__(self, len):
self.leng = len
self.lis = []
def push(self, data):
lis_len = len(self.lis)
if lis_len < self.leng:
self.lis.append(data)
else:
self.lis.append(data)
# 去掉第一个数据。
self.lis = self.lis[1:]
# 反转,这样最新的数据就在最前面了
def get_reverse(self):
return self.lis[::-1]
视图函数:
class LogDataView(GenericAPIView, ViewSetMixin):
# 日志信息
def get(self, request):
flag = True
# 前端传递过来要读取的日志条数
number = int(request.query_params.get('number'))
if number > 100 or number < 1:
return ApiResponse(code=500, msg='失败', error='搜索范围在1-100之间!!')
#拿到读取文件的生成器
data = log_data('warning.log')
# 自己封装的一个队列
queue = Queue(number)
while flag:
try:
line = str(next(data))
if line.startswith('&&'):
#对数据进行操作,获取需要的数据
y, level, time, module, message = line.split('&&')
if level == 'WARNING':
dic = {'level': level, 'time': time, 'module': module, 'message': message, 'color': '#d25e32'}
else:
dic = {'level': level, 'time': time, 'module': module, 'message': message, 'color': '#930808'}
# 将数据入队列
queue.push(dic)
except StopIteration:
# 如果生成器读到文件最后,继续next就会报错,捕获后就退出循环
flag = False
# 将生成的字典传递给前端进行展示,这个是自己封装的response
# 拿到最新的number条日志
dat = queue.get_reverse()
#记录拿到的数据数
log_len = len(dat)
return ApiResponse(data=dat, lenth=log_len)
使用生成器,可以节省我们的内存资源。
通过自己封装的队列,可以拿到固定条数的数据,而不是将所有文件内容都放到内存中,再通过分割拿到最新数据。
|