最近,线上的业务系统不太稳定,需要分析下访问情况,能拿到的数据只有 nginx 服务器的访问日志,不过难不倒我,用合适的工具,分分钟做出图形化展示,看看怎么做的吧
思路
nginx 访问日志,记录了每次客户端请求,其中包括 ip、时间、使用的客户端等信息
通过解析每行数据,提取这些信息,然后对信息进行整理,并做一些必要的统计
最后将统计数据展示出来,可以直观地感知数据中蕴含的问题
基本思路就是这样,不过知道和做到之间地距离还有很远,为了达到目标,需要一些工具做支持
由于数据是 nginx 访问日志,所有不需要爬取,从服务器上下载就好
整理处理过程,除了 python 本身一些功能外,还离不开 pandas 的支持
最后数据展示部分,用的是 Flask + echarts,从头写,确实很有挑战,不过今天我们利用 TurboWay 同学的框架 bigdata_practice,就能轻松搞定
闲话少叙,开始吧
数据处理
下载到 nginx 访问日志,从 nginx 配置文件中可以查看日志存放地址,另外,本文源码中有附带示例日志文件,可下载使用
日志文件为文本文件,每行记录一条访问情况,例如:
124.64.19.27 - - [04/Sep/2020:03:21:12 +0800] "POST /api/hb.asp HTTP/1.1" 200 132 "http://erp.example.com/mainframe/main.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36" "-"
读取文本文件的行,实现比较简单,这里只对提取字段和通过 ip 确定省份做下说明
提取
提取字段的方法如下:
import re
obj = re.compile(r'(?P<ip>.*?)- - \[(?P<time>.*?)\] "(?P<request>.*?)" (?P<status>.*?) (?P<bytes>.*?) "(?P<referer>.*?)" "(?P<ua>.*?)"')
result = obj.match(line)
# print(result.group("time"))
# ip处理
ip = result.group("ip").split(",")[0].strip() # 如果有两个ip,取第一个ip
# 状态码处理
status = result.group("status") # 状态码
# 时间处理
time = result.group("time").replace(" +0800", "") # 提取时间,并去掉时区信息
t = datetime.datetime.strptime(time, "%d/%b/%Y:%H:%M:%S") # 格式化
# request处理
request = result.group("request")
a = request.split()[1].split("?")[0] # 提取请求 url,去掉查询参数
# user_agent处理
ua = result.group("ua")
if "Windows NT" in ua:
u