首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python如何分析Nginx的日志?

Python如何分析Nginx的日志?

原创
作者头像
智维攻城狮
发布2025-08-29 14:44:12
发布2025-08-29 14:44:12
4910
举报
文章被收录于专栏:Linux运维Linux运维

Python如何分析Nginx的日志?

1. 前言

Nginx 作为高性能 Web 服务器和反向代理,广泛应用于生产环境。运维和开发人员经常需要分析其访问日志(access.log)与错误日志(error.log),以便进行流量统计、性能优化、安全审计等工作。 相比 awkgrep 等命令行工具,Python 在可扩展性、数据处理能力、可视化方面更具优势,尤其适合做自动化日志分析

2. Nginx 日志格式解析

2.1 常见 access.log 格式

nginx.conf 中,常见的 log_format 配置如下:

nginx

代码语言:javascript
复制
log_format main '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '"$http_referer" "$http_user_agent" "$request_time"';

示例日志:

代码语言:javascript
复制
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

请求耗时(秒)

3. Python 解析 Nginx 日志

3.1 使用正则表达式解析

代码语言:javascript
复制
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)

3.2 使用 pandas 做统计分析

代码语言:javascript
复制
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())

4. 高级分析场景

4.1 识别异常流量(如 CC 攻击)

代码语言:javascript
复制
# 每个IP的请求次数
ip_counts = df['ip'].value_counts()
​
# 阈值:一分钟内超过100次请求
suspicious_ips = ip_counts[ip_counts > 100].index
print("疑似攻击IP:", suspicious_ips.tolist())

4.2 URL 热点分析

代码语言:javascript
复制
print(df['url'].value_counts().head(10))

4.3 按时间段统计流量

代码语言:javascript
复制
df['hour'] = df['time'].dt.hour
print(df.groupby('hour')['ip'].count())

5. 性能优化建议

  • 批量读取:日志文件大时,建议分块读取或使用 gzip 处理压缩日志。
  • 异步分析:结合 asyncio 或多进程加速解析。
  • 日志切割:配合 logrotate 定期切割,避免单文件过大。
  • 可视化:结合 matplotlib / seaborn 绘制流量趋势图。

Nginx 日志分析不仅能帮助我们了解网站访问情况,还能快速发现性能瓶颈与安全风险。相比纯文本统计,可视化图表能让数据更直观、更易于决策。

6. 日志解析函数(沿用之前的正则)

代码语言:javascript
复制
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 None

7. 数据加载与 DataFrame 构建

代码语言:javascript
复制
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)

8. 可视化分析

8.1 每小时访问量趋势图

代码语言:javascript
复制
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()

8.2 状态码分布饼图

代码语言:javascript
复制
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()

8.3 前10热门 URL 柱状图

代码语言:javascript
复制
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()

8. 运行效果

运行后你将得到三张图表:

  1. 折线图:展示一天中各小时的访问趋势,方便发现高峰期。
  2. 饼图:直观显示 200、404、500 等状态码的比例。
  3. 柱状图:列出访问量最高的 10 个 URL,便于优化热点页面。

9. 优化建议

  • 字体支持:在 matplotlib 中设置 SimHeiMicrosoft YaHei 避免中文乱码。
  • 自动化:可将脚本加入 cron 定时任务,每天生成图表并推送到邮件/钉钉。
  • 大数据处理:日志量大时可用 daskPySpark 替代 pandas
  • 安全监控:结合 IP 黑名单、请求频率阈值,实时阻断恶意流量。

总结

使用 Python 分析 Nginx 日志的优势在于:

  • 灵活性:可根据业务需求定制分析逻辑。
  • 可扩展性:可接入数据库、可视化平台(如 Grafana、Kibana)。
  • 自动化:可定时运行脚本,生成日报/周报。

在生产环境中,建议将日志分析脚本与监控告警系统结合,实现实时安全与性能监控。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python如何分析Nginx的日志?
    • 1. 前言
    • 2. Nginx 日志格式解析
      • 2.1 常见 access.log 格式
    • 3. Python 解析 Nginx 日志
      • 3.1 使用正则表达式解析
      • 3.2 使用 pandas 做统计分析
    • 4. 高级分析场景
      • 4.1 识别异常流量(如 CC 攻击)
      • 4.2 URL 热点分析
      • 4.3 按时间段统计流量
    • 5. 性能优化建议
    • 6. 日志解析函数(沿用之前的正则)
    • 7. 数据加载与 DataFrame 构建
    • 8. 可视化分析
      • 8.1 每小时访问量趋势图
      • 8.2 状态码分布饼图
      • 8.3 前10热门 URL 柱状图
    • 8. 运行效果
    • 9. 优化建议
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档