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))

 

posted on 2022-05-08 08:40  墙角一枝花  阅读(836)  评论(0编辑  收藏  举报