分析 Nginx 日志可以帮助我们了解服务器性能、流量来源、用户行为,以及诊断问题(如错误和攻击)。以下是详细的分析方法:
1. 日志类型
Nginx 有两种主要日志:
- 访问日志 (Access Log):记录客户端对服务器的每个请求。
- 错误日志 (Error Log):记录服务器运行中出现的错误。
访问日志格式
典型日志格式:
text
$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"
字段解释:
$remote_addr
: 客户端 IP 地址。$remote_user
: 认证的用户(如果有)。$time_local
: 本地时间。$request
: 请求方法、路径和协议。$status
: HTTP 状态码。$body_bytes_sent
: 发送的响应大小。$http_referer
: 请求的来源页面。$http_user_agent
: 客户端的 User-Agent 字符串。
2. 常见分析场景
(1) 流量分析
统计访问量、热门资源和请求来源:
-
统计访问 IP:
bashawk '{print $1}' access.log | sort | uniq -c | sort -nr | head
说明:统计每个 IP 的访问次数。
-
统计访问 URL:
bashawk '{print $7}' access.log | sort | uniq -c | sort -nr | head
说明:统计最常访问的路径。
-
统计 Referer:
bashawk -F'"' '{print $4}' access.log | sort | uniq -c | sort -nr | head
说明:查看流量来源。
(2) 状态码分析
找出出现错误的请求:
-
统计状态码分布:
bashawk '{print $9}' access.log | sort | uniq -c | sort -nr
说明:统计每种 HTTP 状态码的次数。
-
筛选特定状态码请求(如 404 错误):
bashawk '$9 == 404 {print $0}' access.log
(3) 排查慢请求
找出处理时间最长的请求(需要启用 $request_time
或 $upstream_response_time
变量):
-
按处理时间排序 :
bashawk '{print $10 " " $7}' access.log | sort -nr | head
说明:找到耗时最长的请求。
(4) 攻击检测
-
检测频繁访问的 IP:
bashawk '{print $1}' access.log | sort | uniq -c | sort -nr | head
说明:可能是攻击者尝试暴力请求。
-
检测恶意 User-Agent:
bashawk -F'"' '{print $6}' access.log | sort | uniq -c | sort -nr | head
(5) 错误日志排查
查看 Nginx 错误日志,定位问题:
bash
tail -f /var/log/nginx/error.log
结合时间、错误码和描述信息,找出具体问题(如后端服务连接失败、配置错误等)。
3. 工具辅助分析
日志切割工具
日志可能很大,按日期切割以便于管理:
-
使用 logrotate 配置自动切割。
-
手动切割:
bashmv access.log access.log.$(date +%Y%m%d) systemctl reload nginx
分析工具
-
GoAccess (实时分析):
安装后运行:
bashgoaccess /path/to/access.log --log-format=COMBINED -o report.html
生成直观的 HTML 报告。
-
AWStats (流量统计):
对 Nginx 访问日志进行详细的统计分析。
4. 性能优化思路
通过分析日志,发现问题后可采取以下措施:
-
高频 IP 限制 :
配置
limit_req
或使用防火墙阻止恶意 IP。nginxlimit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
-
静态文件缓存 :
减少重复请求对服务器的压力。
-
优化后端服务 :
根据慢请求分析,优化后端接口或数据库查询。
5. 示例综合分析
假设你收到很多 502 错误,分析步骤:
-
查看错误日志中的时间点和原因:
bashgrep '502' /var/log/nginx/error.log
-
对比访问日志,找到 502 错误对应的请求和 IP:
bashawk '$9 == 502 {print $1, $7}' access.log
-
检查后端服务是否正常,查看响应时间。