一、前言

性能场景中的业务模型建立是性能测试工作中非常重要的一部分。而在我们真实的项目中,业务模型跟线上的业务模型不一样的情况实在是太多了。原因可能多种多样,这些原因大大降低了性能测试的价值。

今天的文章中,我想写的是最简单的逻辑。那就是从基于网关 access 日志统计分析转化到具体的场景中的通用业务模型。

详细的介绍请参考《性能测试实战30讲》 中的 【14丨性能测试场景:如何理解业务模型?】

通用业务场景模型。就是将这一天的所有业务数加在一起,再将各业务整天的交易量加在一起,计算各业务量的比例。

二、前置工作

首先我们从高峰日取出一天的网关 access 日志,这里示例大概有 1400+ 万的记录

[root@k8s-worker-4 ~]# wc -l access.log 
14106419 access.log

至于网关 access 日志如何配置,可以参看之前的文章 SpringCloud 日志在压测中的二三事

我们得到的 access 日志内容一般如下:

/Feb/2021:13:52:14 +0800] "POST /mall-order/order/generateOrder HTTP/1.1" 500 133 8201 52 ms

对应的字段如下:

address, user, zonedDateTime, method, uri, protocol, status, contentLength, port, duration.

那么,我们的需求来了,如何通过分析 access 日志,获取每个接口网关处理时间最大值、最小值、平均值及访问量。这里我扩展了获取每个接口网关处理时间的统计分析,方便我们对接口的性能评估。

三、编写 Python 脚本完成数据分析

我们知道在数据分析、机器学习领域一般推荐使用到 Python,因为这是 Python 所擅长的。而在 Python 数据分析工作中,Pandas 的使用频率是很高的,如果我们日常的数据处理工作不是很复杂的话,你通常用几句 Pandas 代码就可以对数据进行规整。

那么这里我们只需要将日志中 duration 字段存放到 pandas 的基础数据结构 DataFrame 中,然后通过分组、数据统计功能就可以实现。

整个工程一共包括 4 个部分:

  • 第一个部分为数据加载,首先我们通过 open 文件读数据加载到内存中。注意日志文件比较大的情况下读取不要用readlines()、readline(),会将日志全部读到内存,导致内存占满。因此在此使用 for line in fo 迭代的方式,基本不占内存实现懒加载;
  • 第二步为数据预处理。读取日志文件,可以使用 pd.read_table(log_file, sep=’ ‘, iterator=True),但是此处我们设置的 sep 无法正常匹配分割,因此先将日志用 split 分割,然后再存入 pandas;
  • 第三步为数据分析,Pandas 提供了 IO 工具可以将大文件分块读取,使用不同分块大小来读取再调用 pandas.concat 连接 DataFrame,然后使用 Pandas 常用的统计函数分析;
  • 最后一步为数据装载,把统计分析结果保存到 Excel 文件中。

下载依赖库:

#pip3 install 包名 -i 源的url 临时换源
#清华大学源:https://pypi.tuna.tsinghua.edu.cn/simple/

# 强大的数据结构库,用于数据分析,时间序列和统计等
pip3 install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple/ 

# 处理 URL 的包 
pip3 install urllib -i https://pypi.tuna.tsinghua.edu.cn/simple/ 

# 安装生成execl表格的相关模块 
pip3 install xlwt -i https://pypi.tuna.tsinghua.edu.cn/simple/

具体的代码如下:

#统计每个接口的处理时间
#请提前创建 log 并设置 logdir
import sys
import os
import pandas as pd
from urllib.parse import urlparse
import re

'''
全局参数
'''
mulu=os.path.dirname(__file__)
#日志文件存放路径
logdir="D:\log"
#存放统计所需的日志相关字段
logfile_format=os.path.join(mulu,"access.log")

print ("read from logfile \n")

'''
数据加载及预处理
'''
for eachfile in os.listdir(logdir):
    logfile=os.path.join(logdir,eachfile)
    with open(logfile, 'r') as fo:
        for line in fo:
            spline=line.split()
            #过滤字段中异常部分
            if spline[6]=="-":
                pass
            elif spline[6]=="GET":
                pass
            elif spline[-1]=="-":
                pass
            else:
                #解析成url地址
                parsed = urlparse(spline[6])
                # print('path    :', parsed.path)
                #排除数值参数
                interface = ''.join([i for i in parsed.path if not i.isdigit()])
                # print(interface)
                #重新写入文件
                with open(logfile_format, 'a') as fw:
                    fw.write(interface)
                    fw.write('\t')
                    fw.write(spline[-2])
                    fw.write('\n')
print ("output panda")

'''
数据分析
'''
#将统计的字段读入到dataframe中
reader=pd.read_table(logfile_format,sep='\t',engine='python',names=["interface","duration(ms)"] ,header=None,iterator=True)
loop=True
chunksize=10000000
chunks=[]
while loop:
    try:
        chunk=reader.get_chunk(chunksize)
        chunks.append(chunk)
    except StopIteration:
        loop=False
        print ("Iteration is stopped.")

df=pd.concat(chunks)
#df=df.set_index("interface")
#df=df.drop(["GET","-"])

df_groupd=df.groupby('interface')
df_groupd_max=df_groupd.max()
df_groupd_min= df_groupd.min()
df_groupd_mean= df_groupd.mean()
df_groupd_size= df_groupd.size()

'''
数据装载
'''
df_ana=pd.concat([df_groupd_max,df_groupd_min,df_groupd_mean,df_groupd_size],axis=1,keys=["max","min","average","count"])
print ("output excel")
df_ana.to_excel("result.xls")

运行结果:

这样我们轻松得到了高峰日各业务量统计以及接口处理时间等数据。

四、小结

通过今天的例子我们应该能看到采用 Python 对于性能工程师来说降低了数据分析的技术门槛。相信在当今的 DT 时代,任何岗位都需要用到数据分析的思维和能力。

本文源码:

  • https://github.com/zuozewei/blog-example/tree/master/Performance-testing/02-testdata/gateway-accesslog-analyse

参考资料:

    • [1]:《性能测试实战30讲》

如何使用 Python 统计分析 access 日志?的更多相关文章

  1. 【转】Python之向日志输出中添加上下文信息

    [转]Python之向日志输出中添加上下文信息 除了传递给日志记录函数的参数(如msg)外,有时候我们还想在日志输出中包含一些额外的上下文信息.比如,在一个网络应用中,可能希望在日志中记录客户端的特定 ...

  2. Python 中 logging 日志模块在多进程环境下的使用

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,Python 中 logging 日志模块在多进程环境下的使用 使用 Pytho ...

  3. paip. 解决php 以及 python 连接access无效的参数量。参数不足,期待是 1”的错误

    paip. 解决php 以及 python 连接access无效的参数量.参数不足,期待是 1"的错误 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源 ...

  4. elk收集分析nginx access日志

    elk收集分析nginx access日志 首先elk的搭建按照这篇文章使用elk+redis搭建nginx日志分析平台说的,使用redis的push和pop做队列,然后有个logstash_inde ...

  5. python高效解析日志入库

    python脚本解析日志文件入库一般有三个重要的步骤:读文件.解析文件.入库.在这三个方面下功夫,可确保我们获得最优的性能(这里不讨论并发) 1 读文件:一次读一行,磁盘IO太多,效率低下:一次性读如 ...

  6. Python切割nginx日志_小组_ThinkSAAS

    Python切割nginx日志_小组_ThinkSAAS Python切割nginx日志

  7. Python操作Access数据库

    我们在这篇文章中公分了五个步骤详细分析了Python操作Access数据库的相关方法,希望可以给又需要的朋友们带来一些帮助. AD: Python编 程语言的出现,带给开发人员非常大的好处.我们可以利 ...

  8. 用anaconda的pip安装第三方python包的日志

    用anaconda的pip安装第三方python包的日志 启动anaconda命令窗口: 开始> 所有程序> anaconda> anaconda prompt 会得到两行提示: D ...

  9. Python Web-第二周-正则表达式(Using Python to Access Web Data)

    0.课程地址与说明 1.课程地址:https://www.coursera.org/learn/python-network-data/home/welcome 2.课程全名:Using Python ...

随机推荐

  1. WDK 标准数据类型

    刚刚看到vs2012可以完美支持wdk开发,心中窃喜,正要下载,竟然看到xp不在其支持范围内, 这让刚刚从win7换过来的我真是DT,算了,还是和学习资料保持一致,反正学习的重点不是方便 正题: 为了 ...

  2. SpringBoot面向切面编程(AOP)

    Aspect (与SpringBoot整合) 总结 作用位置 try{ try{ @Around 前置环绕通知 @Before 前置通知 method.invoke(..); }catch(){ @A ...

  3. Go语言源码分析之unsafe

    Go语言源码分析之unsafe 1.什么是unsafe unsafe 库让 golang 可以像C语言一样操作计算机内存,但这并不是golang推荐使用的,能不用尽量不用,就像它的名字所表达的一样,它 ...

  4. 多种方法实现实现全排列 + sort调用标准函数库函数的简述

    全排列:所有不同顺序的元素组组成的一个集合.这里使用使用递归实现全排列. 使用递归算算法呢,首先我们先找一下结束的条件:我们要对一组元素(这里使用数字举例)实现全排列,临界条件就是递归到只有一个元素的 ...

  5. 一文带你详细介绍c++中的std::move函数

    前言 在探讨c++11中的Move函数前,先介绍两个概念(左值和右值) 左值和右值 首先区分左值和右值 左值是表达式结束后依然存在的持久对象(代表一个在内存中占有确定位置的对象) 右值是表达式结束时不 ...

  6. C#是怎么跑起来的

    解释流程前,需要了解一些基本的概念. 基本概念解释: CPU :中央处理器,计算机的大脑,内部由数百万至数亿个晶体管组成,是解释和运行最终转换成机器语言(二进制代码)的地方.机器语言是通过CPU内存的 ...

  7. 一文搞懂:java中的VO、PO、BO、DAO、POJO

    针对java工程里的各种带O的对象,进行分析,了解各自的作用. PO:persistent object,持久对象.与数据库里表字段一一对应.PO是一些属性,以及set和get方法组成.一般情况下,一 ...

  8. 【转载】Linux字符集和系统语言设置-LANG,locale,LC_ALL,POSIX等命令及参数详解

    Linux字符集和系统语言设置-LANG,locale,LC_ALL,POSIX等命令及参数详解 1清风揽月10人评论5006人阅读2017-06-21 15:48:43   博文说明[前言]: 本文 ...

  9. sed -i 's/Search_String/Replacement_String/g' Input_File sed详细手册

    本文列出的十五个例子可以帮助你掌握 sed 命令.如果要使用 sed 命令删除文件中的行,去下面的文章.注意:由于这是一篇演示文章,我们使用不带 -i 选项的 sed 命令,该选项会在 Linux 终 ...

  10. IT菜鸟之思科模拟实验(PT)

    思科官方的模拟软件:cisco packet tracer 网卡端口类型: Ethernet(以太网) 十兆 FastEthernet 百兆 GigabitEthernet 千兆 交换机的端口默认都是 ...