目录

  • pymysql组装sql入库日志
  • 代码组织
  • 将入库的日志通过flask前端展示

pymysql组装sql入库日志

pymysql模块的用法

采集这些指标(metirc)都是linux环境,会用到mysql,做为数据的存储,我用docker来启动

docker run  \
-p 3306:3306 \
-v /data/mysql:/var/lib/mysql \
-v /etc/localtime:/etc/localtime \
--name mysql5 \
--restart=always \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.6.23 \
--character-set-server=utf8 \
--collation-server=utf8_general_ci
create database mem;
create table mem_used(used int, time int)- 时间格式
>>> import time
>>> time.time()
1516860432.386474- 入库后是整形,db自动处理, 也可以入库前int(time).
MySQL [mem]> select * from mem_used;
+-----------+------------+
| used      | time       |
+-----------+------------+
| 628658176 | 1516842082 |
| 628813824 | 1516842083 |
| 628936704 | 1516842084 |
| 628936704 | 1516842085 |
...

一个用法实例, 获取指标(通过psutil模块直接获取到已使用的内存) 也可以自己算出.

import psutil
import time
import pymysql as mscon = ms.connect(host='127.0.0.1', user='root', passwd='123456', db='mem')
con.autocommit(True)
cur = con.cursor()while True:used = psutil.virtual_memory().usedsql = 'insert into mem_used values(%s,%s)' % (used / 1024 / 1024, int(time.time()))  ## Mbcur.execute(sql)time.sleep(1)- %s可以接受任意类型的值

后面会将db操作封装成模块.

说下本次的任务

  • 本次的任务是将apache的access.log的(ip+状态)+出现次数, 入库到mysql里做分析. 分析网站访问的top10
  • 日志样式如下, 以空格分隔 arr[0] arr[8] 分别是ip和状态码
61.159.140.123 - - [23/Aug/2014:00:01:42 +0800] "GET /favicon.ico HTTP/1.1" 404 \ "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36 LBBROWSER" "-"
  • 通过pymysql模块操作mysql数据库

  • 将结果放在res={}一个大的字典里. 核心统计思路如下. 如果字典无key,则value初始化为1; 如果字典有key,则 以key对应的value +1

- 为何是这种格式,取决于echarts数据格式所需. 通常是找到一个合适的图,对图中数据胸有程序,即可以看到它需要一些什么数据,在看下echarts代码,看下需要什么格式的数据, 然后后端组装, json.dumps后返回.res[(ip, status)] = res.get((ip, status), 0) + 1
  • 对字典的值排序
- 遍历日志文件,获取到一个大的字典如下
res = {('182.145.101.123', '200'): 302, ('139.205.220.131', '404'): 1, ('119.146.75.13', '304'): 10, ('59.39.103.85', '200'): 56, ... }- 对字典排序 转成 列表  后插入
print sorted(res.items(), key=lambda x: x[1], reverse=True)[(('123.174.51.164', '200'), 6930), (('117.63.146.40', '200'), 1457), (('118.112.143.148', '404'), 1336), (('111.85.34.165', '200'), 1325), ...]- 对排序后的列表(字典),字符串拼接sql,并插入数据库
for i in sorted(res.items(), key=iambda x: x[1], reverse=True):sql = "insert into iog vaiues ('%s','%s','%s')" % (i[0][0], i[0][1], i[1])db.execute(sql)

代码组织

入库代码

log2db.py

#!/usr/bin/env python
# coding=utf-8from dbutils import DB# 连接mysql
db = DB(host="127.0.0.1",user="root",passwd="",db="logtest"
)# 日志处理成一个大的指定格式的字典(已统计好出现的次数) ((ip, status), count)
res = {}
with open('log.txt') as f:for line in f:if line == "\n":continuearr = line.split(" ")ip = arr[0]status = arr[8]res[(ip, status)] = res.get((ip, status), 0) + 1# 组合sql,执行sql入库日志
for l in sorted(res.items(), key=lambda x: x[1], reverse=True):# {('192.168.1.1',404): 1000,('192.168.1.1',403): 3000,('192.168.1.1',200): 2000,}sql = "insert into log values ('%s','%s','%s')" % (l[0][0], l[0][1], l[1])db.execute(sql)

dbutils.py

#!/usr/bin/env python
# coding=utf-8import pymysql as msclass DB:def __init__(self, host, user, passwd, db):self.host = hostself.user = userself.passwd = passwdself.db = dbself.connect()def connect(self):self.conn = ms.connect(host=self.host,user=self.user,passwd=self.passwd,db=self.db)self.conn.autocommit(True)self.cursor = self.conn.cursor()def execute(self, sql):try:self.cursor.execute(sql)except Exception as e:self.cursor.close()self.conn.close()self.connect()return self.execute(sql)else:return self.cursor# def query(self,tables):#     sql = 'select * from users'#     self.cursor.execute(sql)#     return self.cursor.fetchall()

下载实例日志: https://github.com/lannyMa/flask_info/blob/master/demo5/log.txt

执行脚本入库

python log2db.py

结果查看

入库完成后, flask前端展示+echarts

将入库的日志通过flask前端展示

难点是找图形的数据模型,即json数据格式. 后端返回. 所以当一幅图出来后,要对其上面有啥数据,啥数据是后端返回的,要胸有成竹, 通过代码+浏览器f12conson.log打印出来.

echarts官网上去看最简单实例的教程,用flask展示出来

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>ECharts</title><!-- 引入 echarts.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.0.2/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data: ['销量']},xAxis: {data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);
</script>
</body>
</html>

echarts.min.js路径替换下

flask启动展示

from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')
def index():return render_template('demo.html')if __name__ == '__main__':app.run(debug=True)

先找一个合适的echarts图,观察它所需的接口数据格式,后设计接口

计划使用echarts这个饼图展示

它的源码如下

option = {title : {text: '某站点用户访问来源',subtext: '纯属虚构',x:'center'},tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} ({d}%)"},legend: {orient: 'vertical',left: 'left',data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']},series : [{name: '访问来源',type: 'pie',radius : '55%',center: ['50%', '60%'],data:[{value:335, name:'直接访问'},{value:310, name:'邮件营销'},{value:234, name:'联盟广告'},{value:135, name:'视频广告'},{value:1548, name:'搜索引擎'}],itemStyle: {emphasis: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]
};

下载后,修改echarts-pie.html源码

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>ECharts</title><!-- 引入 echarts.js --><script src="/static/jquery.min.js"></script><script src="/static/echarts.min.js"></script>
</head>
<body><!-- 为ECharts准备一个具备大小(宽高)的Dom画布 -->
<div id="main" style="width: 600px;height:400px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: '某站点用户访问来源',{#            subtext: '纯属虚构',#}x: 'center'},tooltip: {trigger: 'item',formatter: "{a} <br/>{b} : {c} ({d}%)"},toolbox: {feature: {saveAsImage: {show: true}}},legend: {orient: 'vertical',left: 'left',{#            data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']#}},series: [{name: '访问来源',type: 'pie',radius: '55%',center: ['50%', '60%'],{#                data: [#}{#                    {value: 335, name: '直接访问'},#}{#                    {value: 310, name: '邮件营销'},#}{#                    {value: 234, name: '联盟广告'},#}{#                    {value: 135, name: '视频广告'},#}{#                    {value: 1548, name: '搜索引擎'}#}{#                ],#}itemStyle: {emphasis: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]};//使用jq去访问api获取得到数据.$.getJSON('/piedata', function (res) {option.legend.data = res.legendoption.series[0].data = res.data// 使用刚指定的配置项和数据显示图表-绑定数据myChart.setOption(option);})
</script>
</body>
</html>

我们知道了前端js需要的数据所需要的数据格式后,就从后端构造这样的api,供前端调用

- api需返回数据的格式
{"data": [{"name": 200, "value": 49691}, {"name": 206, "value": 32}, {"name": 301, "value": 2}, {"name": 304, "value": 7584}, {"name": 403, "value": 1}, {"name": 404, "value": 3858}], "legend": [200, 206, 301, 304, 403, 404]}- js访问接口方法
$.getJSON('/piedata', function (res) {option.legend.data = res.legendoption.series[0].data = res.datamyChart.setOption(option);  //获取后直接绑定
})

设计top10状态码的api

  • 目标是
即访问
http://127.0.0.1:5000/piedata返回json数据:{"data": [{"name": 200, "value": 49691}, {"name": 206, "value": 32}, {"name": 301, "value": 2}, {"name": 304, "value": 7584}, {"name": 403, "value": 1}, {"name": 404, "value": 3858}], "legend": [200, 206, 301, 304, 403, 404]}
  • 查库后得到的结果
- 用sql语句做数据汇聚,查出status 和 对应的总数, 按照状态码总数来排序
select status,sum(count) from log group by status;

查询结果如下

  • flask写api

- cur.fetchall返回的结果,需对其遍历,重组一定格式的数据
((200, Decimal('49691')), (206, Decimal('32')), (301, Decimal('2')), (304, Decimal('7584')), (403, Decimal('1')), (404, Decimal('3858')))@app.route("/piedata")
def piedata():sql = "select status,sum(count) from log group by status";cur = db.execute(sql)# 构造前端所需的数据结构res = {'legend': [],'data': []}for c in cur.fetchall():code = c[0]count = int(c[1])res['legend'].append(code)res['data'].append({'name': code,'value': count})print(res)return json.dumps(res)- 重组后数据格式如下
{'data': [{'name': 200, 'value': 49691}, {'name': 206, 'value': 32}, {'name': 301, 'value': 2}, {'name': 304, 'value': 7584}, {'name': 403, 'value': 1}, {'name': 404, 'value': 3858}], 'legend': [200, 206, 301, 304, 403, 404]}- 通过json模块处理后返回给将这批数据返回给前端

最终访问

实现前端html展示

@app.route("/")
def index():return render_template("echarts-pie.html")

最终效果:

小结

转载于:https://www.cnblogs.com/iiiiiher/p/8244145.html

[py]access日志入mysql-通过flask前端展示相关推荐

  1. MySQL存储日志并使用Loganalyzer作为前端展示

    MySQL存储日志并使用Loganalyzer作为前端展示 为什么要使用日志 在生产环境中我们可能需要一个较为完整的日志系统来查看运行中主机服务的状态和所作出的操作,我们可以在较大型的网络架构中使用E ...

  2. 【期末大作业】二手房Python爬虫+Flask前端展示+Echarts可视化大项目

    目录 前言 一.项目目标 二.使用工具 三.结果展示 总结 前言 爬虫 :一段自动抓取互联网信息的程序,从互联网上抓取对于我们有价值的信息. Python 爬虫架构主要由五个部分组成,分别是调度器.U ...

  3. 【数据库】浅入MySQL优化

    浅入MySQL优化 前言 抛开过程谈结果的都是傻叉领导.. 在下不会做这种事,先来简单看一遍MySQL的运行机制 ①.建立连接 通过客户端/服务器通信协议与MySQL建立连 接.MySQL 客户端与服 ...

  4. ELK之收集日志到mysql数据库

    写入数据库的目的是持久化保存重要数据,比如状态码.客户端浏览器版本等,用于后期按月做数据统计等. 环境准备 linux-elk1:10.0.0.22,Kibana ES Logstash Nginx ...

  5. mysql 日志节点恢复_基于binlog二进制日志的MySQL恢复笔记

    基于binlog二进制日志的MySQL恢复笔记 刚好复习到这里,顺手做个小实验,记录下. 总的操作流程: step0.关掉数据库的对外访问[防止用户操作继续写入这个库] step1.mysqlbinl ...

  6. python web access_利用python分析access日志的方法

    前言 WAF上线之后,处理最多的是误报消除. 产生误报有多种原因,比如web应用源码编写时允许客户端提交过多的cookie:比如单个参数提交的数值太大. 把误报降低到了可接受的范围后,还要关注漏报.W ...

  7. 微信表情符号 mysql_Emoji表情符号入MySQL数据库报错的解决方案

    Emoji表情符号入MySQL数据库报错的解决方案 发布时间:2020-08-15 08:21:52 来源:ITPUB博客 阅读:136 作者:bestpaydata auther:Jane.Hoo ...

  8. python的flask前端显示图片_python Flask中返回图片流给前端展示

    python Flask中返回图片流给前端展示 image DHogan 2017-05-16 14:50:48 image 20440 image 收藏 12 版权 场景需求:需要在Flask服务器 ...

  9. python的flask前端显示图片_python 实现Flask中返回图片流给前端展示

    场景需求:需要在Flask服务器的本地找一张图片返回给前端展示出来. 问题疑点:通常前端的标签只会接受url的形式来展示图片,没试过在返回服务器本地的一张图片给前端. 因此写个记录一下这个看起来有点奇 ...

最新文章

  1. 城市大脑的定义与理论基础综述
  2. TiKV 源码解析系列文章(二)raft-rs proposal 示例情景分析
  3. 一个openMP编程处理图像的示例
  4. linux基础知识点总结-最实用!(环境搭建,系统分区,常用命令,vim文本)
  5. python启动远端 exe_python打包exe开机自动启动的实例(windows)
  6. 2021年软考VRRP虚拟路由冗余技术
  7. 字节跳动《算法中文手册》高清版.pdf
  8. Windows 10 系统优化脚本大全
  9. python人工智能难不难_AI人工智能难不难 怎么进入人工智能行业
  10. Java基础知识面试题(总结最全面的面试题)
  11. 开源 Python IDE PyScripter设置中文界面
  12. ERROR 1819 (HY000): Your password does not satisfy the current policy requirements的解决方法
  13. hdu 4114 Disney's FastPass 状压dp
  14. Tableau 5阶桑基图
  15. OFD格式的电子发票文件怎么免费转换成PDF
  16. 罗甸脐橙|“橙”心实意——礼誉生态农业
  17. 如何设置无需fn直接按F1~F10
  18. AndroidVideoCache库的基本使用
  19. 我的世界、DotA IMBA常用游戏指令
  20. C#发起钉钉审批实例,表格明细 FormComponentValues_的格式该如何传递的问题

热门文章

  1. 烂泥:学习tomcat之通过shell批量管理多个tomcat
  2. weblogic服务器保存图片失败解决办法
  3. Flash Builder4.7极其简单破解方法-三步搞定(亲测)
  4. 定时发送服务器运行数据并设置阀值警报方法
  5. 夏日炎炎,请照顾好你的电脑
  6. VB 金额大小写转换(两种方法)
  7. Deep Metric Learning for Person Re-Identification
  8. 论文笔记 《Maxout Networks》 《Network In Network》
  9. Leetcode 141. 环形链表 解题思路及C++实现
  10. 4行关键代码实现灰色模型GM(1, 1)