3分钟掌握Nginx日志分析, Nginx日志分析必备

艺帆风顺 发布于 2025-04-30 16 次阅读


 

Nginx作为现代Web架构中最流行的反向代理和Web服务器之一,其作为网站流量入口, 日志文件包含了大量有价值的信息。我们可以通过分析这些日志,了解网站的实际运行状况、用户行为模式,并及时发现潜在问题。本文将详细介绍如何使用命令行工具和脚本对Nginx日志进行深入分析,涵盖从基础统计到高级异常检测的各种常用命令。

Docker 是一个强大的容器化平台,广泛用于开发、测试和生产环境。通过 Docker 命令行工具(CLI),我们可以轻松管理容器、镜像、网络和卷等资源。本文将详细介绍 Docker 的常用命令,带你从入门到熟练掌握 Docker 的核心操作。

Docker 是一个强大的容器化平台,广泛用于开发、测试和生产环境。通过 Docker 命令行工具(CLI),我们可以轻松管理容器、镜像、网络和卷等资源。本文将详细介绍 Docker 的常用命令,带你从入门到熟练掌握 Docker 的核心操作。

一、 Nginx日志格式解析

在开始分析之前,我们需要了解Nginx的日志格式。典型的Nginx访问日志格式如下(可以在nginx.conf中通过log_format指令自定义):

log_format  timed_combined  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for" '                        '$request_time $upstream_response_time';

这个 Nginx 日志格式 timed_combined 定义了多个字段,每个字段记录了 HTTP 请求的不同信息。

  • $remote_addr: 客户端的 IP 地址(直接访问服务器的 IP)
  • $remote_user: HTTP 基本认证中的用户名(如果启用认证)
  • $time_local: 服务器本地时间的访问时间戳,格式通常为 [日/月/年:时:分:秒 时区]
  • $request: 客户端请求的原始 HTTP 方法、路径和协议版本。
  • $status: 服务器返回的 HTTP 状态码。
  • $body_bytes_sent: 发送给客户端的响应体字节数(不含响应头)
  • $http_referer: 请求的来源页面 URL(即用户从哪个链接跳转过来)
  • $http_user_agent: 客户端的用户代理(浏览器、设备等信息)
  • $http_x_forwarded_for: 此字段记录客户端 IP
  • $request_time: 服务器处理请求的总时间(从接收到客户端第一个字节到发送完响应,单位:秒)。
  • $upstream_response_time: 如果请求被代理到上游服务器(如 PHP-FPM、后端服务),此字段记录上游服务器的响应时间(单位:秒)

一条实际的日志记录可能如下所示:

79.95.86.141 - - [28/Apr/2025:01:29:06 +0000"POST /keepalive HTTP/2.0" 200 60 "https://www.google.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36" "79.95.86.141" 0.024 0.023
二、 常用日志分析
1. 统计今日请求最多的URL
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -n 20
  • 命令解析:
    • grep $(date +%d/%b/%Y): 筛选出今天的日志(格式如28/Apr/2025)
    • awk '{print $7}': 提取URL(第7个字段)
    • sort: 排序URL以便统计
    • uniq -c: 统计每个URL出现的次数
    • sort -nr: 按出现次数降序排序
    • head -n 20: 只显示前20条结果
2. 统计某个时间段请求最多的URL
awk '$4 >= "[28/Apr/2025:01:00:00" && $4  /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -n 20
3. 找出访问次数最多的10个IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10
4. 找出某个时间段访问最多的IP
awk '$4 >= "[28/Apr/2025:01:00:00" && $4  /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10
5. 找出响应超过n秒的URL

当我们想找出响应时间超过5秒的请求(需要日志中包含响应时间字段,需要在log_format中添加$request_time):

awk '$NF > 5 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -5
6. 实时筛选Nginx日志
tail -f /var/log/nginx/access.log

结合grep进行实时筛选,例如只显示404错误:

tail -f /var/log/nginx/access.log | grep '" 404 '

更高级的实时监控可以使用ngxtop工具或者goaccess, 本文不做介绍!可自行查询!

7. 统计每秒的QPS

计算每秒的请求量可以帮助我们了解流量情况:

awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2-3 | uniq -c

更精确的每秒QPS统计:

awk '{split($4, a, ":"); print a[2]":"a[3]":"a[4]}' /var/log/nginx/access.log | sort | uniq -c

要统计特定时间段的QPS变化:

awk '$4 >= "[28/Apr/2025:01:00:00" && $4 "[28/Apr/2025:02:00:00"' /var/log/nginx/access.log | awk '{split($4, a, ":"); print a[2]":"a[3]":"a[4]}' | sort | uniq -c

8. 实时统计QPS:

tail -/var/log/nginx/access.log | awk '{    split($4, time, ":");    key = time[2":" time[3":" time[4];    count[key]++;    print key, count[key];}'

三、 日志分析工具推荐

虽然命令行工具强大,但对于大规模日志分析,专业工具更高效:

  • GoAccess
    • 实时Web日志分析工具,支持多种日志格式:
goaccess /var/log/nginx/access.log -/var/www/html/report.html --log-format=COMBINED
  • AWStats
    • 经典的Web日志分析工具,提供丰富的统计报表
  • ELK Stack (Elasticsearch, Logstash, Kibana)
    • Logstash: 日志收集和解析
    • Elasticsearch: 存储和索引日志
    • Kibana: 数据可视化和仪表板
    • 完整的日志收集、分析和可视化解决方案
、 自动化日志监控方案
  • 异常请求报警脚本
#!/bin/bash# 监控最近5分钟内404错误率ERROR_COUNT=$(awk -v d1="$(date --date="-5 min" "+[%d/%b/%Y:%H:%M")" -v d2="$(date "+[%d/%b/%Y:%H:%M")" '$4 >= d1 && $4  /var/log/nginx/access.log | wc -l)TOTAL_COUNT=$(awk -v d1="$(date --date="-5 min" "+[%d/%b/%Y:%H:%M")" -v d2="$(date "+[%d/%b/%Y:%H:%M")" '$4 >= d1 && $4  /var/log/nginx/access.log | wc -l)ERROR_RATE=$(echo "scale=2; $ERROR_COUNT*100/$TOTAL_COUNT" | bc)if (( $(echo "$ERROR_RATE > 5" | bc -l) )); then    echo "High error rate detected: $ERROR_RATE%" | mail -s "Nginx Error Alert" admin@example.comfi
  • 自动封禁恶意IP
    • 使用fail2ban可以实现自动封禁频繁尝试攻击的IP, 本文不做详细介绍!
四、 总结

有效的日志分析不仅仅是技术问题,更需要你对业务的理解和问题的敏感度。定期回顾日志分析策略,随着业务发展不断调整,才能让日志数据发挥最大价值。

如果你有特定场景或问题,欢迎留言讨论!希望这篇文章对你有所帮助!