开发一个web工具分析nginx访问日志

414 阅读2分钟

我的博客网站有时候会被黑客光顾,短时间有大量的request涌入(1s内有上百上千的并发访问),直接导致CPU爆表,造成网站无法正常访问,于是考虑写一个日志分析工具

实施步骤

主要有三步:

  • 通过正则提取访问日志里的关键信息
  • 处理提取的数据(将日期处理为javascript可识别的日期格式)。
  • 数据渲染到页面,可通过用户界面操作、查看、分析日志数据

编写正则表达式

日志截图.png

通过观察发现日志有以下格式:第一部分为IP,然后是两个横杠,紧接着第二部分日期,然后空格分开双引号里是访问路径;每条记录占一行。

我这里准备提取三部分数据:

  • 访问源的IP
  • 访问日期
  • 访问路径

于是编写以下正则:

//多行、全局匹配
const matchAllReg = /^(\d+\.\d+\.\d+\.\d+)\s-\s-\s\[([^\]]+)\]\s"([^"]+)"/mg;
const matchAllResult = logTextContent.matchAll(matchAllReg)
//matchAllResult 是一个包含三个捕获(IP、日期、URL)的迭代器,可通过for...of迭代遍历

接下来就是通过JavaScript提供的FileReaderreadAsText方法读取日志文件的文本内容,然后根据正则规则进行数据提取.

将日期转换为时间戳

由于日期是12/Nov/2020:21:23:19 +0800的格式,Js是无法识别的,因此需要进行日期格式的转换,这里我打算将其转换为时间戳类似: 2020-11-12 21:23:19

const enToNumb = {
  Jan:"01",
  Feb:"02",
  Mar:"03",
  Apr:"04",
  May:"05",
  Jun:"06",
  Jul:"07",
  Aug:"08",
  Sep:"09",
  Oct:"10",
  Nov:"11",
  Dec:"12"
}
let nginxDateStr = "12/Nov/2020:21:23:19 +0800"
nginxDateStr = nginxDateStr.slice(0,20);// 12/Nov/2020:21:23:19
const dateFragArr = nginxDateStr.split(":")[0].split("/").reverse();//["2020","Nov","12"]
dateFragArr[1] = enToNumb[dateFragArr[1]];//将月份格式由英文改为数字

const timeFrag = nginxDateStr.split(":").slice(1,4);// 21:23:19
const timeStamp = dateFragArr.join("-") + " " + timeFrag;

数据渲染到页面

梳理了下自己的需求,并进行简单的分析,设计了以下功能点:

  • 读取本机的日志文本格式文件
  • 提取日志里的三部分数据:IP、访问日期、访问路径(URL)
  • 根据过滤条件(IP、访问日期)进行数据的筛选和过滤
  • 以IP分组进行数据统计,查看某个IP的访问次数

以上功能可以帮助我筛选某个时间段内服务器的访问量,统计并识别哪些是恶意IP(非正常的高频次访问),在安全控制台将其屏蔽。

最终界面

默认界面

未过滤.png

条件过滤(IP、日期)

IP过滤.png

日期.png

分组统计

分组.png

最后附上本工具的线上地址:Nginx日志分析工具