Nginx 作为高性能 Web 服务器和反向代理,广泛应用于生产环境。运维和开发人员经常需要分析其访问日志(access.log)与错误日志(error.log),以便进行流量统计、性能优化、安全审计等工作。 相比 awk、grep 等命令行工具,Python 在可扩展性、数据处理能力、可视化方面更具优势,尤其适合做自动化日志分析。
access.log 格式在 nginx.conf 中,常见的 log_format 配置如下:
nginx
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$request_time"';示例日志:
192.168.1.10 - - [28/Aug/2025:14:32:10 +0800] "GET /index.html HTTP/1.1" 200 1024 "-" "Mozilla/5.0" "0.003"字段含义:
字段 | 含义 |
|---|---|
$remote_addr | 客户端 IP |
$time_local | 本地时间 |
$request | 请求方法 + URL + 协议 |
$status | HTTP 状态码 |
$body_bytes_sent | 响应字节数 |
$http_referer | 来源页面 |
$http_user_agent | 客户端 UA |
$request_time | 请求耗时(秒) |
import re
from datetime import datetime
# Nginx 日志正则
log_pattern = re.compile(
r'(?P<ip>\S+) - (?P<user>\S+)
\[(?P<time>.*?)\]
'
r'"(?P<method>\S+) (?P<url>\S+) (?P<protocol>\S+)" '
r'(?P<status>\d{3}) (?P<size>\d+) "(?P<referer>.*?)" "(?P<agent>.*?)" "(?P<req_time>[\d\.]+)"'
)
def parse_log_line(line):
match = log_pattern.match(line)
if match:
data = match.groupdict()
# 转换时间格式
data['time'] = datetime.strptime(data['time'], "%d/%b/%Y:%H:%M:%S %z")
data['status'] = int(data['status'])
data['size'] = int(data['size'])
data['req_time'] = float(data['req_time'])
return data
return None
# 示例
with open("/var/log/nginx/access.log", encoding="utf-8") as f:
for line in f:
log_data = parse_log_line(line)
if log_data:
print(log_data)pandas 做统计分析import pandas as pd
# 读取并解析日志
records = []
with open("/var/log/nginx/access.log", encoding="utf-8") as f:
for line in f:
data = parse_log_line(line)
if data:
records.append(data)
df = pd.DataFrame(records)
# 统计访问量前10的IP
print(df['ip'].value_counts().head(10))
# 统计状态码分布
print(df['status'].value_counts())
# 平均响应时间
print(df['req_time'].mean())# 每个IP的请求次数
ip_counts = df['ip'].value_counts()
# 阈值:一分钟内超过100次请求
suspicious_ips = ip_counts[ip_counts > 100].index
print("疑似攻击IP:", suspicious_ips.tolist())print(df['url'].value_counts().head(10))df['hour'] = df['time'].dt.hour
print(df.groupby('hour')['ip'].count())gzip 处理压缩日志。asyncio 或多进程加速解析。logrotate 定期切割,避免单文件过大。matplotlib / seaborn 绘制流量趋势图。Nginx 日志分析不仅能帮助我们了解网站访问情况,还能快速发现性能瓶颈与安全风险。相比纯文本统计,可视化图表能让数据更直观、更易于决策。
import re
from datetime import datetime
log_pattern = re.compile(
r'(?P<ip>\S+) - (?P<user>\S+)
\[(?P<time>.*?)\]
'
r'"(?P<method>\S+) (?P<url>\S+) (?P<protocol>\S+)" '
r'(?P<status>\d{3}) (?P<size>\d+) "(?P<referer>.*?)" "(?P<agent>.*?)" "(?P<req_time>[\d\.]+)"'
)
def parse_log_line(line):
match = log_pattern.match(line)
if match:
data = match.groupdict()
data['time'] = datetime.strptime(data['time'], "%d/%b/%Y:%H:%M:%S %z")
data['status'] = int(data['status'])
data['size'] = int(data['size'])
data['req_time'] = float(data['req_time'])
return data
return Noneimport pandas as pd
records = []
with open("/var/log/nginx/access.log", encoding="utf-8") as f:
for line in f:
data = parse_log_line(line)
if data:
records.append(data)
df = pd.DataFrame(records)import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="whitegrid", font="SimHei") # 支持中文
df['hour'] = df['time'].dt.hour
hourly_counts = df.groupby('hour')['ip'].count()
plt.figure(figsize=(10, 5))
sns.lineplot(x=hourly_counts.index, y=hourly_counts.values, marker="o")
plt.title("每小时访问量趋势")
plt.xlabel("小时")
plt.ylabel("访问次数")
plt.show()status_counts = df['status'].value_counts()
plt.figure(figsize=(6, 6))
plt.pie(status_counts, labels=status_counts.index, autopct='%1.1f%%', startangle=90)
plt.title("HTTP状态码分布")
plt.show()top_urls = df['url'].value_counts().head(10)
plt.figure(figsize=(12, 6))
sns.barplot(x=top_urls.values, y=top_urls.index, palette="viridis")
plt.title("前10热门URL")
plt.xlabel("访问次数")
plt.ylabel("URL")
plt.show()运行后你将得到三张图表:
matplotlib 中设置 SimHei 或 Microsoft YaHei 避免中文乱码。cron 定时任务,每天生成图表并推送到邮件/钉钉。dask 或 PySpark 替代 pandas。使用 Python 分析 Nginx 日志的优势在于:
在生产环境中,建议将日志分析脚本与监控告警系统结合,实现实时安全与性能监控。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。