以下是基于 Python 3 的完整脚本,用于分析 Nginx 日志并生成 Excel 和图片报告。假设日志格式为标准 combined
格式(如不匹配需调整正则)。
1. 安装依赖库
pip3 install pandas matplotlib openpyxl
2. Python 脚本 (nginx_log_analysis.py
)
import re
import pandas as pd
import matplotlib.pyplot as plt
from collections import defaultdict
import argparse
from datetime import datetime
# 配置参数
parser = argparse.ArgumentParser(description='Analyze Nginx logs and generate reports.')
parser.add_argument('--log', type=str, default='/var/log/nginx/access.log', help='Path to Nginx access log file')
parser.add_argument('--excel', type=str, default='nginx_report.xlsx', help='Output Excel file name')
parser.add_argument('--image', type=str, default='nginx_report.png', help='Output image file name')
args = parser.parse_args()
# 正则匹配Nginx日志格式(combined)
log_pattern = r'(?P<ip>\S+) - (?P<user>\S+)$$
(?P<time>.+?)
$$ "(?P<method>\S+) (?P<url>\S+) (?P<protocol>\S+)" (?P<status>\d+) (?P<size>\d+) "(?P<referer>.*?)" "(?P<ua>.*?)"'
# 解析日志
def parse_log(log_path):
data = []
with open(log_path, 'r') as f:
for line in f:
match = re.match(log_pattern, line)
if match:
fields = match.groupdict()
# 转换时间格式
fields['time'] = datetime.strptime(fields['time'], '%d/%b/%Y:%H:%M:%S %z')
data.append(fields)
return pd.DataFrame(data)
# 主分析逻辑
def analyze_logs(df):
# 转换数据类型
df['status'] = df['status'].astype(int)
df['size'] = df['size'].astype(int)
# 统计结果
stats = {
'top_ips': df['ip'].value_counts().head(10),
'top_urls': df['url'].value_counts().head(10),
'status_codes': df['status'].value_counts(),
'hourly_traffic': df.set_index('time').resample('H').size(),
'referers': df['referer'].value_counts().head(10),
'user_agents': df['ua'].value_counts().head(10)
}
return stats
# 生成Excel
def save_to_excel(stats, excel_file):
with pd.ExcelWriter(excel_file) as writer:
# 原始数据
df.to_excel(writer, sheet_name='Raw Data')
# 统计结果
for name, data in stats.items():
data.to_excel(writer, sheet_name=name.capitalize())
# 生成图片
def save_to_image(stats, image_file):
plt.figure(figsize=(15, 10))
# 子图1:Top IPs
plt.subplot(2, 2, 1)
stats['top_ips'].plot(kind='bar', title='Top 10 Client IPs')
# 子图2:状态码分布
plt.subplot(2, 2, 2)
stats['status_codes'].plot(kind='pie', autopct='%1.1f%%', title='HTTP Status Code Distribution')
# 子图3:每小时请求量
plt.subplot(2, 2, 3)
stats['hourly_traffic'].plot(kind='line', title='Hourly Request Trend')
# 子图4:Top URLs
plt.subplot(2, 2, 4)
stats['top_urls'].plot(kind='barh', title='Top 10 Requested URLs')
plt.tight_layout()
plt.savefig(image_file)
plt.close()
# 执行主流程
if __name__ == '__main__':
# 解析日志
df = parse_log(args.log)
# 分析数据
stats = analyze_logs(df)
# 保存结果
save_to_excel(stats, args.excel)
save_to_image(stats, args.image)
print(f"[+] Report saved to {args.excel} and {args.image}")
3. 运行脚本
python3 nginx_log_analysis.py \
--log /var/log/nginx/access.log \
--excel report.xlsx \
--image report.png
4. 输出说明
-
Excel 文件 (
report.xlsx
):Raw Data
工作表:原始日志解析后的数据。Top_ips
工作表:访问量最高的前10个IP。Status_codes
工作表:HTTP状态码分布。Hourly_traffic
工作表:每小时的请求量趋势。
-
图片 (
report.png
):- 包含4个子图:
- 客户端IP访问量Top 10(柱状图)
- HTTP状态码分布(饼图)
- 每小时请求趋势(折线图)
- 请求URL Top 10(横向柱状图)
- 包含4个子图:
5. 自定义日志格式
如果日志格式不同(例如自定义格式),需调整脚本中的 log_pattern
正则表达式。例如,若日志包含 $request_time
,可添加字段:
log_pattern = r'(?P<ip>\S+) - (?P<user>\S+)$$
(?P<time>.+?)
$$ "(?P<method>\S+) (?P<url>\S+) (?P<protocol>\S+)" (?P<status>\d+) (?P<size>\d+) "(?P<referer>.*?)" "(?P<ua>.*?)" (?P<request_time>\d+\.\d+)'
6. 扩展功能建议
- 异常处理:添加对日志解析失败的容错。
- 大数据优化:使用
Dask
或pandas
分块读取处理大文件。 - 更多图表:通过
seaborn
或plotly
生成交互式图表。 - 邮件通知:通过
smtplib
自动发送报告。
此脚本提供基础分析框架,可根据实际需求扩展功能。