本文目录导读:

这是一个非常实用的需求,答案是:完全可以,而且有很多现成的脚本和工具可以自动分析 Nginx 访问日志。
根据你的技术背景和分析深度需求,可以分为以下几种情况:
极简方案:Linux 一行命令(适合快速查看)
如果你不需要图表,只想在服务器上快速知道过去1小时的访问量、IP、状态码,可以用 awk + sort + uniq 组合。
示例1:统计访问量最高的10个IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
示例2:统计返回最多的HTTP状态码
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
示例3:统计访问最多的URL(去除参数)
awk '{print $7}' /var/log/nginx/access.log | cut -d? -f1 | sort | uniq -c | sort -rn | head -10
优点: 零依赖,随用随跑。
缺点: 无法处理大日志(GB级别),无法做复杂分析。
实用脚本:Python 版分析脚本(推荐)
写一个 30-50 行的 Python 脚本,可以自动分析并输出报告,这里提供一个可直接复制使用的脚本,它支持自动解析、Top N、404统计。
脚本特点:
- 自动按行读取(内存友好,可处理几GB日志)
- 统计:总请求、唯一IP数、TOP IP、TOP URL、404来源
- 支持按时间范围过滤(通过
grep或脚本内过滤)
#!/usr/bin/env python3
# nginx_log_analyzer.py - 简单实用的Nginx日志分析器
import sys
import re
from collections import Counter
def analyze_log(filepath, top_n=10):
"""分析Nginx默认combined格式日志"""
ip_pattern = re.compile(r'^(\d+\.\d+\.\d+\.\d+)')
url_pattern = re.compile(r'"(?:GET|POST|HEAD|PUT|DELETE) (/\S*)')
status_pattern = re.compile(r'" (\d{3}) ')
ip_counter = Counter()
url_counter = Counter()
url_404_counter = Counter()
status_counter = Counter()
total_requests = 0
traffic_bytes = 0
try:
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
total_requests += 1
# 提取IP
ip_match = ip_pattern.match(line)
if ip_match:
ip_counter[ip_match.group(1)] += 1
# 提取URL
url_match = url_pattern.search(line)
if url_match:
url = url_match.group(1)
url_counter[url] += 1
# 提取状态码
status_match = status_pattern.search(line)
if status_match:
status = status_match.group(1)
status_counter[status] += 1
if status == '404':
url_404_counter[url] += 1
# 提取字节数(第10个字段,默认格式)
parts = line.split()
if len(parts) >= 10 and parts[-1].isdigit():
traffic_bytes += int(parts[-1])
except FileNotFoundError:
print(f"错误:文件 {filepath} 未找到")
return
# 输出报告
print(f"{'='*50}")
print(f"📊 Nginx 访问日志分析报告")
print(f"{'='*50}")
print(f"📄 日志文件: {filepath}")
print(f"📈 总请求数: {total_requests:,}")
print(f"🌐 唯一IP数: {len(ip_counter):,}")
print(f"💾 总流量: {traffic_bytes/1024/1024:.2f} MB")
print()
print("🏆 Top 10 访问最多的IP:")
for ip, count in ip_counter.most_common(top_n):
print(f" {ip:20s} -> {count:>8,} 次")
print()
print("🔗 Top 10 访问最多的URL:")
for url, count in url_counter.most_common(top_n):
print(f" {url:40s} -> {count:>8,} 次")
print()
print("🔴 返回404最多的URL:")
for url, count in url_404_counter.most_common(top_n):
print(f" {url:40s} -> {count:>8,} 次")
print()
print("📊 HTTP状态码分布:")
for status, count in status_counter.most_common():
print(f" {status:5s} -> {count:>8,} 次 ({(count/total_requests)*100:.1f}%)")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: python3 nginx_log_analyzer.py /var/log/nginx/access.log [top_n]")
sys.exit(1)
logfile = sys.argv[1]
top_n = int(sys.argv[2]) if len(sys.argv) > 2 else 10
analyze_log(logfile, top_n)
使用方法:
python3 nginx_log_analyzer.py /var/log/nginx/access.log # 指定显示前20条 python3 nginx_log_analyzer.py /var/log/nginx/access.log 20
自动化持续监控:Crontab + 日志切割分析
你可以让脚本每天自动运行,并把结果发邮箱或存文件。
Crontab 配置(每天凌晨1点分析昨天的日志):
0 1 * * * /usr/bin/python3 /root/scripts/nginx_log_analyzer.py /var/log/nginx/access.log.$(date -d 'yesterday' +\%Y\%m\%d) > /var/reports/$(date -d 'yesterday' +\%Y\%m\%d)_report.txt
更高级的选择:直接使用现成工具
如果不想造轮子,以下工具更强大:
| 工具 | 特点 | 安装 |
|---|---|---|
| GoAccess | 终端实时分析、生成HTML报告 | apt install goaccess |
| ngxtop | 类似top命令,实时监控 | pip install ngxtop |
| Webalizer / AWStats | 老牌,生成静态图表页面 | apt install webalizer |
| ELK Stack | 企业级全链路分析 | 较重,适合大规模 |
GoAccess 使用示例(最简单,实时查看):
# 直接实时分析日志文件(类似top) goaccess /var/log/nginx/access.log -c # 生成漂亮的HTML报告 goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED
注意事项
- 日志格式:如果你的 Nginx 自定义了日志格式(比如加了
$request_time),需要修改脚本中的正则表达式。 - 大文件处理:Python 版本采用逐行读取,可以处理几GB的日志,如果日志特别巨大(几十GB),建议用 GoAccess(基于C语言)或
awk脚本。 - 安全:分析脚本建议以普通用户权限运行,避免完全读取敏感日志。
总结推荐
- 临时看一眼 → 用开头的一行
awk命令 - 日常需要报告 → 用上面的 Python 脚本(直接复制保存为
.py文件就行) - 需要图表和持续监控 → 装个
goaccess,一行命令生成 HTML
你可以根据自己的运维习惯选择最合适的方案,如果需要我帮你针对特定的日志格式(比如包含了响应时间、User-Agent)定制分析脚本,可以告诉我你的日志格式。