简介:这是一套面向安全运维与日志分析学习者的命令行Web日志审计工具,基于Python实现,将日志统计、终端可视化与机器学习恶意请求识别整合在一起,适合具备Python基础、希望上手日志审计与异常检测实战的开发者。资源包共63个文件,以35个py源码文件为核心,辅以17张jpg运行截图、4个txt样本与说明、2个ini配置文件及日志、md文档等,压缩包约10.58MB,目录按bin、lib、machine_learning、conf、logs等模块划分,结构清晰。功能上覆盖访问量统计、日志审查、请求统计与恶意请求分析,内置白名单与黑名单样本集及训练数据,可支撑机器学习模型的训练与验证。配置方面通过config.ini连接数据库与日志读取参数,并提供check_conf.py做配置校验,默认使用sqlite,也可选装MySQL。目前已有832人学习,适合作为日志审计与异常检测方向的练手项目或二次开发基础。
1. 从一堆 access.log 到能用的审计结论:这套 Python 工具到底解决什么
手里拿到一个几百 MB 的 Nginx access.log,老板要你半小时内说清楚「有没有人在扫我们」「哪个 IP 最可疑」「昨天下午那波 502 是不是被打的」——这种场景下,grep加awk能顶一阵,但一旦要按时间窗口做统计、按请求特征做异常识别,纯命令行就开始力不从心。这套「基于机器学习的 Web 日志统计分析与异常检测工具」就是冲着这个痛点来的:它是一个跑在终端里的 Web 日志审计工具,把访问量统计、日志审查、请求分布统计和恶意请求分析四件事塞进一个命令行界面,用terminaltables把结果画成表格,用机器学习模型对请求做黑白判定。它适合安全运维、应急响应和做日志分析练手的人,Python 3.6+ 就能跑,默认用标准库sqlite落库,不强制装 MySQL。下面我按「配置 → 跑通 → 调参 → 避坑」的顺序,把它拆成能直接抄的步骤。
2. 环境与配置落地:config.ini 里每个字段到底管什么
这套工具的运行链路是「读日志 → 解析入库 → 统计/建模 → 终端展示」,所以配置错一个字段,后面全是空表或者直接崩。先把环境搭对,再谈分析。
2.1 依赖安装与 Python 版本边界
项目要求 Python 3.6+,requirements.txt里主要是机器学习、数据库和终端表格相关的库。安装命令在项目说明里写的是python -r requirements.txt,这里其实是个笔误,正确写法是带-m pip:
# 建议先建虚拟环境,避免污染系统 Python python3 -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate # 安装依赖,注意是 -m pip 而不是直接 python -r python -m pip install -r requirements.txt逻辑说明:-m pip保证调用的是当前解释器对应的 pip,避免多版本 Python 下装错地方。参数上,如果你的环境里python指向 2.x,全部换成python3。这一步最常见的翻车是terminaltables或机器学习库编译失败,多数是 Python 版本过低或缺少编译工具链,先确认python --version输出 3.6 以上再继续。
2.2 config.ini 关键字段逐项拆解
配置文件在analog根目录下,主要分数据库连接和日志读取两块。默认走 sqlite,如果你不打算上 MySQL,数据库那几项保持默认即可,重点在日志路径和解析规则。
[database] # 默认 sqlite,文件会生成在项目目录下 type = sqlite # 如果用 mysql,下面几项才需要填 host = 127.0.0.1 port = 3306 user = root password = your_password dbname = analog [log] # 待分析的 Web 日志绝对路径,支持 Nginx/Apache 常见格式 path = /var/log/nginx/access.log # 日志格式模板,字段顺序要和真实日志一致 format = $remote_addr - - [$time_local] "$request" $status $body_bytes_sent逻辑说明:type决定走哪套存储后端,sqlite 零配置适合快速验证,MySQL 适合日志量大、要多人共享结果的场景。format是最容易配错的一项——它必须和你的日志真实字段顺序对齐,否则解析出来的 IP、状态码会整体错位,统计结果全是垃圾。参数建议:先用head -n 5 access.log看一眼真实格式,再照着改format,不要照抄示例。
2.3 用 check_conf.py 做配置自检
配完不要急着跑主程序,项目自带check_conf.py,专门用来验证配置正确性:
python check_conf.py逻辑说明:这个脚本会尝试按config.ini连接数据库、读取日志文件并做一次试解析。如果它报「日志文件不存在」或「格式不匹配」,说明路径或format有问题;如果报数据库连接失败,检查type和账号密码。我的习惯是每次换日志源都先跑一遍它,比直接跑main.py再对着报错猜要省事得多。这一步过了,才说明环境真正可用。
3. 跑通主流程:统计、审查与机器学习异常检测怎么串起来
配置自检通过后,main.py是入口。它把日志审计、统计和机器学习识别恶意请求串成一条流水线,理解这条链路,才知道每个功能输出的数字从哪来。
3.1 日志解析入库与访问量统计
主程序启动后会先解析日志并写入数据库,再做统计。核心逻辑大致是这样:
# 简化后的主流程示意,实际以 main.py 为准 from lib import configparser, logger from machine_learning import detector def run(): conf = configparser.load('config.ini') # 读取配置 logger.init(conf) # 初始化日志 # 1. 解析 access.log 并入库 records = parse_and_store(conf['log']['path']) # 2. 访问量、状态码、请求路径统计 stats = build_statistics(records) # 3. 机器学习模型对请求做恶意判定 result = detector.predict(records) render_terminal_table(stats, result) # terminaltables 渲染 if __name__ == '__main__': run()逻辑说明:parse_and_store负责把文本日志转成结构化记录,build_statistics按 IP、URL、状态码聚合,detector.predict才是机器学习那部分。参数上,统计维度由配置和代码里的聚合键决定,想加「按小时分布」就得改聚合逻辑。这一步的产出就是终端里那几张表:访问量统计、请求统计、恶意请求分析。
3.2 机器学习异常检测:训练集与黑白样本
项目在conf/sample_set下带了test_white_log.txt、test_black_log.txt和train.txt,这是模型能工作的前提——白样本是正常请求,黑样本是恶意请求,train.txt用于训练。
# 目录结构(节选) conf/ default_config.ini sample_set/ test_white_log.txt # 正常请求样本 test_black_log.txt # 恶意请求样本 train.txt # 训练数据逻辑说明:模型本质是把请求特征(URL 长度、特殊字符比例、参数个数等)映射成「正常/恶意」二分类。白样本决定模型认为什么是「正常」,黑样本决定它识别什么为「攻击」。参数建议:如果你的业务 URL 风格和自带样本差异大(比如全是 RESTful 带 UUID 的路径),直接套用自带模型误报会很高,需要用自己的日志补充白样本重新训练。这是这套工具能不能真正用起来的分水岭。
3.3 终端图形化输出与结果解读
统计和检测结果通过terminaltables渲染成终端表格,项目_img目录下的截图就是实际输出效果。解读时重点看三列:请求量异常的 IP、状态码集中在 4xx/5xx 的路径、被模型标黑的请求。
# 典型运行 python main.py # 输出为多张终端表格:访问量统计 / 请求统计 / 恶意请求分析逻辑说明:终端表格适合快速排查,不适合长期留存。我的做法是把输出重定向到文件,配合logs/file_log.log一起看。参数上,如果表格太宽在终端里换行错乱,调小终端字号或把输出重定向后用编辑器看。这一步的坑在于:模型标黑不等于真攻击,它只是「偏离白样本」,必须人工二次确认。
4. 避坑与排查:这套工具最容易翻车的五个地方
工具本身不复杂,但日志分析类项目「配置差一点、结果差一片」,下面这几条是我实际拆解时踩过或见别人踩过的。
4.1 现象:统计表全是 0 或空
原因:config.ini里path指向的日志文件不存在,或format与真实日志字段顺序不一致,导致解析出空记录。解决:先ls -l确认路径,再head -n 3对比格式,用check_conf.py验证,别跳过自检。
4.2 现象:恶意请求分析误报一大堆正常 URL
原因:自带黑白样本和你的业务流量分布差异过大,模型把正常但「长得不常见」的 URL 判成恶意。解决:往test_white_log.txt里补充你自己的正常请求样本,重新训练;或先只用统计功能,模型判定作为参考而非结论。
4.3 现象:sqlite 库文件越来越大,查询变慢
原因:每次运行都往同一张表追加记录,没有清理机制。解决:定期备份后删库重建,或改用 MySQL 并加时间分区。日志分析场景下数据增长很快,这一点要提前规划。
4.4 现象:python -r requirements.txt报错
原因:项目说明里的命令少了-m pip,直接python -r会被解释成执行一个叫-r的脚本。解决:用python -m pip install -r requirements.txt,这是标准写法。
4.5 现象:终端表格中文或宽字符错位
原因:terminaltables对东亚宽字符宽度计算不准,列宽对不齐。解决:把输出重定向到文件查看,或临时把终端字体换成等宽字体。属于显示层问题,不影响数据正确性。
5. 进阶技巧:把模型判定变成可复现的验证流程
工具跑通只是起点,真正决定它有没有用的是「你怎么验证模型判得准不准」。我一般会做一件事:拿一批已经人工确认过的日志当测试集,跑一遍模型,统计误报和漏报。
# 用自带样本做一次快速验证的思路 from machine_learning import detector white = load_lines('conf/sample_set/test_white_log.txt') black = load_lines('conf/sample_set/test_black_log.txt') # 白样本被判为恶意的比例 = 误报率 fp = sum(1 for r in white if detector.predict_one(r) == 'malicious') # 黑样本被判为正常的比例 = 漏报率 fn = sum(1 for r in black if detector.predict_one(r) == 'normal') print('误报率: %.2f%%' % (fp / len(white) * 100)) print('漏报率: %.2f%%' % (fn / len(black) * 100))逻辑说明:误报率高说明白样本覆盖不够,漏报率高说明黑样本特征太单一。参数上,这两个比例没有绝对标准,安全场景通常更容忍误报、不能容忍漏报,所以优先补黑样本。跑完这组数字,你才知道这套模型在你的环境里能不能信。
| 验证指标 | 含义 | 偏高时的处理 |
|---|---|---|
| 误报率 | 正常请求被判恶意 | 补充白样本,重训 |
| 漏报率 | 恶意请求被判正常 | 补充黑样本,重训 |
| 覆盖率 | 样本覆盖的请求类型 | 用真实日志扩充样本集 |
还有个小技巧:把main.py的输出和logs/train_log.log对照看,训练日志里会记录模型处理过程,出问题时这是唯一的黑匣子。别嫌日志啰嗦,排查时它就是后悔药。
从那以后我每次拿到新的日志源,都强制先跑一遍check_conf.py再跑验证脚本,确认误报漏报在可接受范围才敢把结论交出去。希望这套拆解能帮你少走点弯路。
本文还有配套的精品资源,点击获取