网络编程
位置:首页>> 网络编程>> 数据库>> 基于python实现cdn日志文件导入mysql进行分析

基于python实现cdn日志文件导入mysql进行分析

作者:??梦想橡皮擦????  发布时间:2024-01-29 07:37:55 

标签:python,cdn,日志,文件,导入,mysql

一、本文需求背景

周六日出现CDN大量请求,现需要分析其请求频次与来源,查询是否存在被攻击问题。

本文以阿里云CDN日志作为辅助查询数据,其它云平台大同小异。

系统提供的离线日志如下所示:

基于python实现cdn日志文件导入mysql进行分析

二、需求落地如下

日志实例如下所示:

[9/Jun/2015:01:58:09 +0800] 10.10.10.10 - 1542 "-" "GET http://www.aliyun.com/index.html" 200 191 2830 MISS "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://example.com/robot/)" "text/html"

其中相关字段的解释如下:

  • [9/Jun/2015:01:58:09 +0800]:日志开始时间。

  • 10.10.10.10:访问IP。

  • -: * 。

  • 1542:请求响应时间,单位为毫秒。

  • "-": HTTP请求头中的Referer。

  • GET:请求方法。

  • http://www.aliyun.com/index.html:用户请求的URL链接。

  • 200:HTTP状态码。

  • 191:请求大小,单位为字节。

  • 2830:请求返回大小,单位为字节。

  • MISS:命中信息。

    • HIT:用户请求命中了CDN边缘节点上的资源(不需要回源)。

    • MISS:用户请求的内容没有在CDN边缘节点上缓存,需要向上游获取资源(上游可能是CDN L2节点,也可能是源站)。

  • Mozilla/5.0(compatible; AhrefsBot/5.0; +http://example.com/robot/):User-Agent请求头信息。

  • text/html:文件类型。

按照上述字段说明创建一个 MySQL 表,用于后续通过 Python 导入 MySQL 数据,字段可以任意定义

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for ll
-- ----------------------------
DROP TABLE IF EXISTS `ll`;
CREATE TABLE `ll`  (
 `id` int(11) NOT NULL,
 `s_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `pro_ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `dura_time` int(11) NULL DEFAULT NULL,
 `referer` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `code` int(255) NULL DEFAULT NULL,
 `size` double NULL DEFAULT NULL,
 `res_size` double NULL DEFAULT NULL,
 `miss` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `ua` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 `html_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
 PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

下载全部日志之后,使用 Python 批量导入数据库中,解析代码如下,在提前开始前需要先看一下待提取的每行数据内容。

[11/Mar/2022:00:34:17 +0800] 118.181.139.215 - 1961 "http://xx.baidu.cn/" "GET https://cdn.baidu.com/video/1111111111.mp4" 206 66 3739981 HIT "Mozilla/5.0 (iPad; CPU OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 SP-engine/2.43.0 main%2F1.0 baiduboxapp/13.5.0.10 (Baidu; P2 15.1) NABar/1.0" "video/mp4"

初看之下,我们会使用空格进行切片,例如下述代码:

import os
# 获取文件名
my_path = r"C:日志目录"
file_names = os.listdir(my_path)
file_list = [os.path.join(my_path, file) for file in file_names]
for file in file_list:
   with open(file, 'r', encoding='utf-8') as f:
       lines = f.readlines()
       for i in lines:
           item_list = i.split(' ')
           s_time = item_list[0]+' '+item_list[1]
           ip = item_list[2],
           pro_ip =item_list[3],
           dura_time =item_list[4],
           referer =item_list[5],
           method =item_list[6],
           url = item_list[7],
           code =item_list[8],
           size =item_list[9],
           res_size =item_list[10],
           miss =item_list[11],
           html_type =item_list[12]
           print(s_time,ip,pro_ip,dura_time,referer,method,url,code,size,res_size,miss,html_type)

运行之后,会发现里面的开始时间位置,UA位置都存在空格,所以该方案舍弃,接下来使用正则表达式提取。

参考待提取的模板编写正则表达式如下所示:

\[(?<time>.*?)\] (?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (?<pro_ip>.*?) (?<dura_time>\d+) \"(?<referer>.*?)\" \"(?<method>.*?) (?<url>.*?)\" (?<code>\d+) (?<size>\d+) (?<res_size>\d+) (?<miss>.*?) \"(?<ua>.*?)\" \"(?<html_type>.*?)\"

接下来进行循环读取数据,然后进行提取:

import os
import re
import pymysql
# 获取文件名
my_path = r"C:日志文件夹"
file_names = os.listdir(my_path)
file_list = [os.path.join(my_path, file) for file in file_names]
wait_list = []
for file in file_list:
   with open(file, 'r', encoding='utf-8') as f:
       lines = f.readlines()
       for i in lines:
           pattern = re.compile(
               '\[(?P<time>.*?)\] (?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (?P<pro_ip>.*?) (?P<dura_time>\d+) \"(?P<referer>.*?)\" \"(?P<method>.*?) (?P<url>.*?)\" (?P<code>\d+) (?P<size>\d+) (?P<res_size>\d+) (?P<miss>.*?) \"(?P<ua>.*?)\" \"(?P<html_type>.*?)\"')
           gs = pattern.findall(i)
           item_list = gs[0]
           s_time = item_list[0]
           ip = item_list[1]
           pro_ip = item_list[2]
           dura_time = item_list[3]
           referer = item_list[4]
           method = item_list[5]
           url = item_list[6]
           code = item_list[7]
           size = item_list[8]
           res_size = item_list[9]
           miss = item_list[10]
           ua = item_list[11]
           html_type = item_list[12]
           values_str = f"('{s_time}', '{ip}', '{pro_ip}', {int(dura_time)}, '{referer}', '{method}', '{url}', {int(code)}, {int(size)}, {int(res_size)}, '{miss}', '{ua}','{html_type}')"
           wait_list.append(values_str)

读取到数据存储到 wait_list 列表中,然后操作列表,写入MySQL,该操作为了防止SQL语句过长,所以每次间隔1000元素进行插入。

def insert_data():
   for i in range(0,int(len(wait_list)/1000+1)):
       items = wait_list[i * 1000:i * 1000 + 1000]
       item_str = ",".join(items)
       inser_sql = f"INSERT INTO ll(s_time, ip, pro_ip, dura_time, referer, method, url,code, size, res_size, miss, ua,html_type) VALUES {item_str}"
       db = pymysql.connect(host='localhost',
                            user='root',
                            password='root',
                            database='logs')
       cursor = db.cursor()
       try:
           cursor.execute(inser_sql)
           db.commit()
       except Exception as e:
           # print(content)
           print(e)
           db.rollback()

最终的结果如下所示:

基于python实现cdn日志文件导入mysql进行分析

导入MySQL之后,就可以按照自己的需求进行排序与查询了。

三、自定义查询

可以通过 refer 计算请求次数:

select count(id) num,referer from ll GROUP BY referer ORDER BY num desc

基于python实现cdn日志文件导入mysql进行分析

来源:https://juejin.cn/post/7076248160330317861

0
投稿

猜你喜欢

  • 一、创建生成器通过列表⽣成式,我们可以直接创建⼀个列表。但是,受到内存限制,列表容量肯定是有限的。⽽且,创建⼀个包含100万个元素的列表,不
  • 前言CSV(Comma-Separated Values)即逗号分隔值,一种以逗号分隔按行存储的文本文件,所有的值都表现为字符串类型(注意:
  • 以前写JS程序的时候,经常碰到了定位的问题。但每次都看到一半,找到需要的属性就了事了。今天下了狠心,要花点时间,彻底地弄明白他。以下内容看着
  • 1.检查mysql是否安装yum list installed | grep mysql如果有的话 就全部卸载yum -y remove +
  • Transformer模型概述Transformer是一种用于序列到序列学习的神经网络架构,专门用于处理输入和输出序列之间的依赖关系。该模型
  • 概述Rollup, 和 Webpack, Parcel 都是模块打包工具(module bundler tool), 但是侧重点不同, 我们
  • 首先是创建一个类,继承于ActionResult,记住要引用System.Web.Mvc命名空间,如下: public class Imag
  • 1、通过%格式表达式可以构建对象的格式化字符串输出。%表达式,由%分隔,左侧为格式字符串,由固定字符串和%开头的格式化样式组成,右侧为实际的
  • 在使用python编程过程中,我们往往需要借助字典来提高编程效率。同时为了调试方便,我们希望将某些变量保存为中间文件。例如,在协同过滤算法中
  • IE 开发团队更改了 IE8 的 User-agent ,更改的部分信息如下:IE8 on Windows Vista (Compatibi
  • 一个日期联动选择器javascript源码,年月日联动显示,准确显示日期(包括闰年日期),可自定义日期范围。 【select】 先说清空一个
  • 人工生命—群集智能—蚁群算法js版前言(摘自网上,代码是自己想出来的)对于普通大众来说,“人工生命”、“群集智能”、“仿生机器人”等等可能是
  • 我就废话不多说了,大家还是直接看代码吧~#!/usr/bin/env python# encoding: utf-8''&#
  • 如:>>> print ord('a') 97 >>> print chr(97) a
  • 背景介绍开发中遇到了一个需求:程序运行到某处时需要用户确认, 但不能一直傻等, 后面的程序不能被一直阻塞, 需要有个超时限制, 也就是这个程
  • 在cssplay网站看到有一组CSS像素画,于是也想摩仿一下,于是在网络上找到一组头像图标,看其结构比较简单,就拿它开刀吧!先看看预览图图一
  • 今天有个哥们问我要是JavaScript函数重名了会有什么后果?开始我没有细想,就说可能会出错吧,可是等我实验完了发现页面没有任何脚本错误提
  • 今天安装Django的时候遇到了python版本冲突,找不到python路径,所以又重新安装了一个python3.6.5安装完之后,突然发现
  • 一、安装我们知道selenium是桌面浏览器自动化操作工具(Web Browser Automation)appium是继承selenium
  • 1. 像素基本操作1.1 读取、修改像素可以通过[行,列]坐标来访问像素点数据,对于多通道数据,返回一个数组,包含所有通道的值,对于单通道数
手机版 网络编程 asp之家 www.aspxhome.com