Python 实战:统计 Nginx 访问日志里的高频 IP 并生成报表
【摘要】 一、需求背景服务器跑了一段时间后,经常会遇到这些问题:到底是哪些 IP 在访问?有没有异常的高频请求?某个接口的调用来源集中在哪?Nginx 的访问日志里其实什么都有,只是直接翻文本效率太低。与其一行行看,不如写个小脚本自动统计。这次就用 Python 实现一个简单的日志分析工具。 二、日志长什么样Nginx 默认的访问日志格式大概是这样的:127.0.0.1 - - [19/Oct/20...
一、需求背景
服务器跑了一段时间后,经常会遇到这些问题:到底是哪些 IP 在访问?有没有异常的高频请求?某个接口的调用来源集中在哪?
Nginx 的访问日志里其实什么都有,只是直接翻文本效率太低。与其一行行看,不如写个小脚本自动统计。这次就用 Python 实现一个简单的日志分析工具。
二、日志长什么样
Nginx 默认的访问日志格式大概是这样的:
127.0.0.1 - - [19/Oct/2026:10:00:00 +0800] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0"
一行日志包含客户端 IP、时间、请求方法、路径、状态码、响应大小、UA 等信息。本文只提取第一列的 IP 做统计,其他字段可以按需扩展。
三、脚本设计思路
整体逻辑很简单:
- 逐行读取日志文件;
- 用正则提取每行开头的 IP 地址;
- 用字典累计每个 IP 出现的次数;
- 按次数排序,取前 N 名;
- 输出到控制台并导出 CSV。
这种"读取—处理—统计—输出"的流程,是日志分析的通用套路,换成分析 URL、状态码、User-Agent 也一样适用。
四、完整代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import csv
import re
from collections import Counter
IP_PATTERN = re.compile(r'^(\d{1,3}(?:\.\d{1,3}){3})')
def count_ips(log_path):
counter = Counter()
with open(log_path, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
match = IP_PATTERN.match(line)
if match:
counter[match.group(1)] += 1
return counter
def export_csv(counter, output_path, top_n):
with open(output_path, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerow(['rank', 'ip', 'count'])
for index, (ip, count) in enumerate(counter.most_common(top_n), start=1):
writer.writerow([index, ip, count])
def main():
parser = argparse.ArgumentParser(description='统计 Nginx 访问日志中的高频 IP')
parser.add_argument('logfile', help='日志文件路径,例如 /var/log/nginx/access.log')
parser.add_argument('--top', type=int, default=20, help='输出前 N 名,默认 20')
parser.add_argument('--output', default='ip_report.csv', help='CSV 输出路径')
args = parser.parse_args()
counter = count_ips(args.logfile)
total = sum(counter.values())
print(f'共解析 {total} 条记录,涉及 {len(counter)} 个 IP\n')
print(f'{"排名":<6}{"IP":<18}{"访问次数":<10}')
for index, (ip, count) in enumerate(counter.most_common(args.top), start=1):
print(f'{index:<8}{ip:<20}{count:<10}')
export_csv(counter, args.output, args.top)
print(f'\n报表已导出到 {args.output}')
if __name__ == '__main__':
main()
五、运行效果
python3 ip_report.py /var/log/nginx/access.log --top 10
输出大致如下:
共解析 128340 条记录,涉及 4213 个 IP
排名 IP 访问次数
1 192.168.1.10 8021
2 203.0.113.25 5170
3 198.51.100.7 3324
...
报表已导出到 ip_report.csv
导出的 CSV 可以直接用 Excel 打开,或者丢给图表工具做可视化。
六、进阶:定时统计
如果希望每天自动生成报表,可以配合 crontab:
0 2 * * * cd /opt/scripts && python3 ip_report.py /var/log/nginx/access.log --top 20 >> ip_report.log 2>&1
建议把报表文件按日期命名,避免被覆盖,例如改成 ip_report_20261019.csv。
七、注意事项
- 日志文件可能被 logrotate 切分,统计前最好先确认当天的文件范围;
- 如果启用了 IPv6,日志第一列可能是
::1之类的地址,需要调整正则; - 日志属于用户访问数据,导出和分享前注意脱敏;
- 数据量特别大时,可以考虑按行流式处理并定期落盘,避免占满内存。
小结
本文用不到百行代码实现了一个日志统计小工具,核心思路就是"正则提取 + 字典计数 + 排序输出"。掌握了这个套路之后,统计 URL、状态码、UA 都是同样的写法。
工具本身不复杂,但日常排障时确实省事。如果你也经常和服务器日志打交道,不妨把它改成适合自己业务的版本。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)