Flask + echarts 轻松解决 nginx 日志可视化

news2024/9/25 11:20:45

最近,线上的业务系统不太稳定,需要分析下访问情况,能拿到的数据只有 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 = "windows"
elif "iPad" in ua:
    u = "ipad"
elif "Android" in ua:
    u = "android"
elif "Macintosh" in ua:
    u = "mac"
elif "iPhone" in ua:
    u = "iphone"
else:
    u = "其他设备"

# refer处理
referer = result.group("referer")

代码看着长,其实逻辑很简单,核心是提取信息的正则表达式,利用了命名分组的方式,匹配后,可以通过命名来提取数据

对提取出的数据,需要处理一下,比如请求时间,采用的是类似 UTC 时间格式,需要去掉时区,并转换为 datatime 类型

另外就是的客户端的处理,根据关键字,判断客户端类型

将提取的信息,存入一个 词典 对象中,即每行对于一个 词典 对象,最后将一个个对象追加到一个 列表 对象中,带进一步处理

获取用户省份

为了后面对访问者所在区域进行分析,需要对一些字段做处理,例如将 ip 转换为省份信息

转换主要利用的是百度的 ip 定位服务

百度的 ip 定位服务,通过认证,可以获得每日 3 万次的免费配额

通过提供的 api 可以获取 ip 地址所在的省名称

考虑到查询效率和配额限制问题,最好对 ip 定位的结果做个缓存:

import requests
import os

ak = "444ddf895 ... a5ad334ee" # 百度 ak 需申请

# ip 定位方法
def ip2province(ip):
    province = ipCache.get(ip, None)
    if province is None:
        url = f"https://api.map.baidu.com/location/ip?ak={ak}&ip={ip}&coor=bd09ll"
        try:
            province = json.loads(requests.get(url).text)['address'].split('|')[1]
            ipCache[ip] = province
            # 这里就需要写入
            with open("ip_cache.txt","a") as f:
                f.write(ip + "\t" + province + "\n")
            return province
        except Exception as e:
            return "未知"
    else:
        return province

# 初始化缓存
ipCache = {}
if os.path.exists("ip_cache.txt"):
    with open("ip_cache.txt", "r") as f:
        data = f.readline()
        while data:
            ip, province = data.strip().split("\t")
            ipCache[ip] = province
            data = f.readline()
  • 首先需要申请一个百度 app key

  • 合成请求,通过 requests  get,得到响应,从中提取到 ip 对应的省份信息

  • 对应地址缓存,将没有缓存的结果存入 ipCache 词典对象,并写入 ip_cache.txt 文件,下次启动时,用缓存文件中的内容初始化 ipCache 词典对象

  • 在每次需要获取 ip 对应地址时,先检查缓存,如果没有才通过 api 获取

数据分析

数据分析,就是对提取到的特征数据做统计加工,利用的是强大的 pandas

通过数据处理过程,我们可以得到处理好的 列表 对象,列表对象很容易创建为 pandas 的 DataFrame

接着,利用 pandas 的统计功能,将原始数据转换为可以展示用的分析数据

最后将数据存入 Excel 文件

def analyse(lst):
    df = pd.DataFrame(lst)  # 创建 DataFrame

    # 统计省份
    province_count_df = pd.value_counts(df['province']).reset_index().rename(columns={"index": "province", "province": "count"})

    # 统计时段
    hour_count_df = pd.value_counts(df['hour']).reset_index().rename(columns={"index": "hour", "hour": "count"}).sort_values(by='hour')

    # 统计客户端
    ua_count_df = pd.value_counts(df['ua']).reset_index().rename(columns={"index": "ua", "ua": "count"})

    # 数据存储
    to_excel(province_count_df, 'data.xlsx', sheet_name='省份')
    to_excel(hour_count_df, 'data.xlsx', sheet_name='按时')
    to_excel(ua_count_df, 'data.xlsx', sheet_name='客户端')

def to_excel(dataframe, filepath, sheet_name):
    if os.path.exists(filepath):j
        excelWriter = pd.ExcelWriter(filepath, engine='openpyxl')
        book = load_workbook(excelWriter.path)
        excelWriter.book = book
        dataframe.to_excel(excel_writer=excelWriter,sheet_name=sheet_name,index=None, header=None)
        excelWriter.close()
    else:
        dataframe.to_excel(filepath, sheet_name=sheet_name, index=None, header=None)
  • analyse 方法,接受一个 列表 对象,即在数据整理部分得到的数据

  • 将数据创建为 DataFrame,利用 pandas 的 value_counts 方法对对应字段数据进行统计,注意,value_counts 会做去重处理,从而统计出每个值出现的个数

  • 因为 value_counts 处理的结果,是一个 Series 对象,索引为不重复的值,所以在用 reset_index 方法处理一下,将索引转换为一个正常列,并对列名做了替换,以便后续处理更方便

  • 由于 value_counts 后的结果是按统计数量从多到少排列的,对应按时间的统计有些奇怪,所以利用 sort_values 方法,按时间列做了重新排序

  • to_excel 方法是为了将数据导出为 excel,可以支持导入不同 sheet,以便做数据展示

数据分析部分,可以从不同的角度对数据进行统计分析,最终将需要展示的数据存入 Excel,当然根据需要也可以存入其他数据库

数据展示

从头利用 Flask 和 echarts 做数据展示是可以的,不过需要处理更多的细节

如果利用一些框架,快速做展示,然后再做局部的个性化调整

这里用到的框架是 TurboWay 的 bigdata_practice,虽然功能比较单一,结构不太灵活,不过用来搭建一个可用的数据展示系统还是没问题的,重要的是可以通过源码学习构建思路的方法

bigdata_practice git 地址为:https://github.com/TurboWay/bigdata_practice.git

将其 clone 到本地

git clone https://github.com/TurboWay/bigdata_practice.git

然后按照依赖模块,在 bigdata_practice 文件夹中,有个 requirements.txt,里面列了项目所依赖的库和组件

关于如何构建 requirements.txt 文件,可参考 《部署 Flask 应用》

进入 bigdata_practice 文件夹,用 pip 安装依赖:

pip install -r requirements.txt

注意:最好使用虚拟环境安装,如何创建虚拟环境,可参考这篇文章

安装依赖之后,就可以启动 Flask 服务了

python app.py

 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 137-055-644
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

如果一切正常,可以访问 localhost:5000,查看数据展示效果

这里对项目中的需要定制的部分做下说明

在 ironman 目录下,app.py 为 Flask 服务主代码,其中定义了系统的访问路径,比如首页、线图、饼图等,这里可以根据自己的需求添加或删改

每个访问路径对应一个页面模板,模板文件存放在,templates 文件夹下,如果需要调整菜单,需要对每个模板页面中的菜单部分进行修改,以调整菜单项目以及被激活的菜单

data.py 定义了展示数据的读取接口,相当于一个数据层,依赖于 nginx_log_data.py,将数据设置为,方便展示的结构,如果需要展示更多的图形,需要根据展示效果,修改或添加新的数据接口

nginx_log_data.py 从 Excel 文件中读取需要展示的数据,Excel 中的数据,就是 数据分析 部分得到的结果,这里利用 pandas 读取 Excel 的功能,如果需要展示更多的分析数据,可以在这里添加数据读取结果,另外通过调整 data.py 以及相应的页面模板文件,将数据得以展示

这里,我们就 24小时访问趋势、客户端占比以及用户分布做了展示,效果如下:

24小时访问趋势

客户端占比

用户分布

实践

下载源码后,先安装项目依赖

pip install -r requirements.txt

示例用的 nginx 访问日志,在 nginx_access.zip 压缩包里,先解压到当前目录

然后申请百度API,获取到 ak,修改到 analyse\baidu_api.py 的 13 行

将命令行切换到代码目录下,否则可能出现文件找不到的错误

执行数据分析脚本:

python .\analyse\main.py

最后启动 Flask 服务:

python .\ironman\app.py

总结

今天利用 pandas、Flask、echarts 对 nginx 服务器的访问日志做了简单分析和展示,完成任务的同时,学习和实践了如何通过一些简单的工具和方法构造一个数据展示平台的过程

文章主要说明了构建思路和需要注意的部分,具体细节,请下载示例代码,运行,同时欢迎交流探讨

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9 CPP结构体注意事项

注意&#xff1a; 1 结构名是标识符 2 结构体的成员可以是任意数据类型 3 定义结构体描述的代码可以放在程序的人和地方&#xff0c;一般放在main函数的上面或头文件中。 4 结构体成员可以用C的类&#xff08;如string&#xff09;&#xff0c;但是不提倡。 5 在C中&#…

java:AES加密和解密

java&#xff1a;AES加密和解密 1 前言 对称加密&#xff0c;即单秘钥加密&#xff0c;指加密和解密的过程中&#xff0c;使用相同的秘钥&#xff0c;相比于非对称加密&#xff0c;因仅有一把钥匙&#xff0c;故而速度更快&#xff0c;更适合解密大文件&#xff08;常见于如视…

ESP32的arduino IDE代码使用flash download tool进行烧录

ESP32的arduino IDE代码使用flash download tool进行烧录前言arduino代码烧录arduino下载了一些什么文件flash download tool工具烧录总结前言 最近遇到用户在使用 arduino IDE开发环境编写了ESP32的代码&#xff0c;希望提供编写好的程序给用户烧录&#xff0c;但是又不希望让…

Kotlin + SpringBoot + JPA 服务端开发

Kotlin SpringBoot JPA 服务端开发 本篇主要介绍一下 kotlin springboot的服务端开发环境搭建 1.概述 Kotlin 是一个基于JVM的编程语言, 是IDEA开发工具 jetbrains 公司开发的语言,也被google选为android开发的首选语言, 因为它是完全兼容Java的 所以也可以做后端开发 比如…

[Java] 如何理解和设置ThreadPoolExecutor三大核心属性?什么情况下工作线程数会突破核心线程数?任务拒绝策略都有哪些?

文章目录前言ThreadPoolExecutor类是什么&#xff1f;ThreadPoolExecutor的三大核心属性1. 核心线程数&#xff08;corePoolSize&#xff09;属性2. 任务队列&#xff08;workQueue&#xff09;属性3. 最大线程数&#xff08;maximumPoolSize&#xff09;属性总结&#xff1a;T…

【开发百宝箱之猿如意使用指南】「工欲成其事,必先利其器」一文教你如何通过“猿如意”便捷的使用数据库管理工具DBeaver

开发百宝箱之猿如意使用指南欢迎您使用“猿如意”百宝箱大家科普一下什么是猿如意&#xff1f;赶快趁热下载个【猿如意】吧每个程序猿值得拥有的学习开发工作必备“良药”没有猿如意的“我们”&#xff08;猿如意帮我们解决了哪些问题&#xff1f;&#xff09;【如何快速下载自…

非零基础自学Golang 第12章 接口与类型 12.2 接口的创建与实现 12.2.1 接口创建

非零基础自学Golang 文章目录非零基础自学Golang第12章 接口与类型12.2 接口的创建与实现12.2.1 接口创建第12章 接口与类型 12.2 接口的创建与实现 Go语言接口是方法的集合&#xff0c;使用接口是实现模块化的重要方式。 下面将重点介绍如何创建和实现一个Go语言接口。 12…

Pytest用例执行的先后顺序

[内部资源] 想拿年薪30W的软件测试人员&#xff0c;这份资料必须领取~ 温馨提示 「本篇约1600字&#xff0c;看完需3-5分钟&#xff0c;学习学半小时&#xff0c;加油&#xff01;」 先看普通函数运行顺序 import pytestdef test_one():print("我是清安")def tes…

React学习27(react-redux多组件共享数据)

项目结构 准备工作 1&#xff09;定义一个person组件&#xff0c;和count组件通过redux共享数据 2&#xff09;为person组件编写&#xff1a;reducer &#xff0c;action和contant常量 3&#xff09;重点&#xff1a;Person的reducer和Count的reducer要用combineReducers进行…

深度学习-优化器

优化器 文章目录优化器1. 引言1. SGD1.1 vanilla SGD1.2 SGD with Momentum1.3 SGD with Nesterov Acceleration2. AdaGrad3. RMSProp4. AdaDelta5. Adam优化器选择出处1. 引言 优化算法可以分成一阶优化和二阶优化算法&#xff0c;其中一阶优化就是指的梯度算法及其变种&#…

Linux——vi,vim的使用

三种模式 正常模式 以vi或vim打开一个档案就直接进入一般模式了(这是默认的模式)。在这个模式中&#xff0c;你可以使用 【上下左右】 按键来移动光标&#xff0c;你可以使用 【删除字符】或 【删除整行】来处理档案内容&#xff0c;也可以使用 【复制&#xff0c;粘贴】来处…

3D激光里程计其三:点云畸变补偿

3D激光里程计其三&#xff1a;点云畸变补偿1. 产生原因2. 补偿方法Reference: 深蓝学院-多传感器融合 1. 产生原因 一帧点云&#xff1a;通常指雷达内部旋转一周扫描得到的点的集合。 优点&#xff1a;有足够数量的点云才能进行匹配&#xff0c;且一周正好是周围环境的完整采…

认识Java中的异常处理

文章目录Java异常处理异常体系的介绍常见运行时异常常见编译时异常Java异常处理 异常体系的介绍 什么事异常处理? 异常是程序在“编译”或者“执行”的过程中可能出现的问题&#xff0c;比如: 数组索引越界、空指针异常、 日期格式化异常&#xff0c;等… 注意&#xff1a;语…

常用损失函数

常见损失函数 文章目录常见损失函数引言回归1. 均方差2.平均绝对误差(MAE)3. 均方根误差(RMSE)4. 交叉熵分类二分类多分类引言 无论在机器学习还是深度领域中,损失函数都是一个非常重要的知识点。损失函数&#xff08;Loss Function&#xff09;是用来估量模型的预测值 f(x) 与…

Eslint 8.23 Flat Config 新配置迁移升级指南

前言 直入正题&#xff0c;eslint 目前为止的配置文件格式&#xff08; 如 .eslintrc.js &#xff09; 存在很多无法避免的历史问题&#xff1a; 配置格式混乱&#xff0c;层层不明确的继承&#xff0c;不易理解。 插件配置时不支持实体运用&#xff08;不能传 function / ob…

学完框架后的反思—为什么要使用框架?

学习前端也有一定的时间了,最近在网上看到了一个问题让我反思了很久——为什么要使用前端框架? 我发现自己当初学习框架时并没有想那么多,只是看中了其在业界企业的应用,大部分公司开发页面基本上都是使用框架进行开发的,而最为被大厂广泛接受的就是 React 框架,所以我当…

二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮 DPPE-PEG-N3简介,可用于药物传递、基因转染和生物分子修饰。

二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮 DPPE-PEG-N3 中文名称&#xff1a;二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮基 英文名称&#xff1a;DPPE-PEG-N3 英文别名&#xff1a; 1,2-dipalmitoyl-sn-glycero-3-phosphoethanolamine-PEG-Azide 分子量&#xff08;PEG&#xff09;&a…

Linux——任务调度

at定时任务 基本介绍 at命令是一次性定时计划任务&#xff0c;at地守护线程atd会以后台模式运行&#xff0c;检查作业队列来运行默认情况下&#xff0c;atd守护进程没60秒检查作业队列&#xff0c;有作业时&#xff0c;会检查作业运行时间&#xff0c;如果时间于当前时间匹配…

Dubbo 1 分布式系统中的相关概念 1.2 集群和 分布式

Dubbo 【黑马程序员Dubbo快速入门&#xff0c;Java分布式框架dubbo教程】 1 分布式系统中的相关概念 文章目录Dubbo1 分布式系统中的相关概念1.2 集群和 分布式1.2.1 集群和分布式1.2.2 集群和分布式 【互联网 中】1.2 集群和 分布式 1.2.1 集群和分布式 集群&#xff1a;很…

使用synchornized和ReentrantLock来解决并发错误

文章目录什么是并发错误&#xff1f;并发错误是如何产生的&#xff1f;演示并发错误如何解决并发错误使用synchornized解决并发错误使用ReentrantLock解决并发错误什么是并发错误&#xff1f; 多个线程共享操作同一个对象的时候&#xff0c;线程体当中连续的多行操作未必能够连…