python-日志分析小工具
一、涉及知识点
【1】with open(file) as f:方法
(1)文件读取;该方法可以try catch报错,并且不需要close关闭文件
【2】读取文件行方法:
(1)f.readline():直接按行读取,会读取出来空行(\n)
(2)f.read().splitlines():先读取所有数据,按行切割,后续用if line:可以排除掉空行
【3】find()方法:
(1)能找到字符串的开始位置,如果要切割两个字符串之间的数据,需要加上第一个字符串的长度
【4】str类型转换成浮点型数据:
(1)需要注意字符串是否有空行、换行等,如果有空行、换行会转换失败,需要先处理后再进行转化
【5】字符串前面的字母含义:
(1)u''----表示后面字符串以 Unicode 格式 进行编码,一般用在含有中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码。
(2)r''----表示字符串去掉转义字符,例如 r'aaa\n' 输出 aaa\n;例如'aaa\n' 输出 aaa 换行
(3)f''----表示字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去:sql = f'insert into test(prod_code,prod_name) values({line})'
(4)b''----表示字符串类型是bytes类型
【6】字符串百分号作用:u'0ms-100ms: %s个,%.2f%%' % (num_100,num_100/totle_num*100)
(1)%s--替代字符串;%d--替代整数;%f 浮点型
(2)第二个% 表示替代前面的位置,如果替代的数据有多个,则用()括起来:'%s %d' % (a,b)
(3)第三个% 是用来转义作用
二、实现步骤:
【1】创建四个列表
【2】打开文件,读取每行数据
【3】如果行内容不为空,查找字符串1,加上字符串1的长度
【4】查找字符2位置,切割字符串,获取字符串1和字符串2之间的目标字符串
【5】转换字符串类型为浮点型
【6】判断浮点型数据的大小,放入到list列表中
【7】计算
三、具体实现
# 一、需求:
# web后台系统日志文件记录了每个服务请求的处理时间
# 开发一个工具,统计处理时间在
# 0-100ms
# 100ms-500ms
# 500ms-1s
# >1s
# 的请求各有多少,百分比为多少
# 二、日志格式:
# 0118_11:32:36 !! op takes 0.02299999064 seconds : function:GET /api/mgr/sq_mgr/
# 三、分析:
# 1、取出日志文件中每一次处理请求的时间,存入相应的容器内(list)
# 2、计算每个时间段容器(list)中处理时间的个数,并计算百分比
# 四、伪代码:
# 1、创建四个list 对应存储不同的响应时间段
# 1.1取出时间字符串
# 1.1.1 先找到要截取字段的前一个值的位置:idx1
# 1.1.2 找到idx1后面的第一个空格的位置:idx2
# 这段日志【idx1:idx2】---两个坐标之间就是要获取的字段
# 1.2判断值,放入对应容器内
# 2、读入日志文件readlines每行内容,依次存入列表
# 创建四个list
list100 = []
list100_500 = []
list500_1000 = []
list1000=[]
# 打开文件读取(默认是读)(为什么用with open方法---该方法可以try catch报错,并且不需要关闭close文件)
with open('/Users/panshaoying/Desktop/database/data/logtest.log') as f:
# 全部读取出来,然后切割每一行数据(如果这边用f.readlines()读取数据,如果有空行,则空行也会被读取出来,后续数据处理会有问题)
lines = f.read().splitlines()
# 如果读取的行不为空
for line in lines:
if line:
# 找到op takes 的位置,find方法找到的是字符串的开始位置,所以要增加字符串的长度
dx1 = line.find('takes ') + len('takes ')
# 找到目标字段的后一个位置
dx2 = line.find(' seconds')
# 字符串截取,从dx1开始到dx2(不包含dx2)位置的字符串
responsetimestr = line[dx1:dx2].strip()
# print(type(responsetimestr))
# print(responsetimestr)
# # 获得的字段是字符串,要进行数据大小判断,需要将字符串转换成浮点型数据
rts = float(responsetimestr)
# 将获取到的数据放到对应的list内
if rts < 0.1:
list100.append(rts)
elif 0.1 <= rts < 0.5:
list100_500.append(rts)
elif 0.5 <= rts < 1:
list500_1000.append(rts)
elif 1 <= rts:
list1000.append(rts)
# print(list100)
# print(list100_500)
# print(list500_1000)
# print(list1000)
# 计算每个列表的长度,就是每个列表内有多少个数据
num_100 = len(list100)
num_100_500 = len(list100_500)
num_500_1000 = len(list500_1000)
num_1000 = len(list1000)
# 计算总数,转换成float,等下除法的时候精度更大
totle_num = float(num_100 + num_100_500 + num_500_1000 + num_1000)
# 计算百分比
# u''----表示后面字符串以 Unicode 格式 进行编码,一般用在含有中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码。
# r''----表示字符串去掉转义字符,例如 r'aaa\n' 输出 aaa\n;例如'aaa\n' 输出 aaa 换行
# f''----表示字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去:sql = f'insert into test(prod_code,prod_name) values({line})'
# b''----表示字符串类型是bytes类型
# %s--替代字符串;%d--替代整数;%f 浮点型
# 第二个% 表示替代前面的位置,如果替代的数据有多个,则用()括起来
# 第三个% 是用来转义作用
print(u'0ms-100ms: %s个,%.2f%%' % (num_100,num_100/totle_num*100))
print(u'100ms-500ms: %s个,%.2f%%' % (num_100_500,num_100_500/totle_num*100))
print(u'num_500_1000ms: %s个,%.2f%%' % (num_500_1000,num_500_1000/totle_num*100))
print(u'num_1000ms: %s个,%.2f%%' % (num_1000,num_1000/totle_num*100))