用 grep、awk 与 sed 快速分析 Nginx 访问日志:定位慢请求与异常 IP 的实操步骤

举报
yd_226757564 发表于 2026/11/10 10:06:16 2026/11/10
【摘要】 网站变慢或出现异常请求时,直接分析 Nginx 访问日志往往最快。本文用 grep、awk 与 sed 三个系统自带工具,演示统计状态码、定位异常 IP、按耗时找慢请求、按接口聚合耗时等实操步骤。

网站变慢或者出现大量异常请求时,第一反应往往是去看监控面板,但很多时候直接分析 Nginx 访问日志更快。本文用 grep、awk 与 sed 这三个系统自带工具,演示一套定位慢请求与异常 IP 的实操步骤,不需要额外安装软件。

一、先确认日志格式与位置

默认的 combined 日志格式大致如下,字段之间用空格分隔:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

常见日志路径是 /var/log/nginx/access.log。先用下面命令确认文件存在,并看一眼真实行长什么样:

ls -lh /var/log/nginx/access.log
head -n 3 /var/log/nginx/access.log

需要注意:默认的 combined 格式不记录请求耗时。如果要分析慢请求,需要在 log_format 末尾加上 $request_time,例如 ... "$http_user_agent" $request_time;,修改后执行 nginx -t && nginx -s reload 使其生效。

二、统计状态码分布,判断故障面

先统计各类状态码的数量,看问题集中在 4xx、5xx 还是普遍变慢:

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

如果想只看 5xx 请求的完整行:

awk '$9 >= 500 && $9 < 600' /var/log/nginx/access.log | head -n 20

三、找出访问量最高的 IP,识别异常来源

按首字段(客户端 IP)分组计数,取前 10 名:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10

如果某个 IP 的请求量比其他 IP 高出一个数量级,同时状态码以 404 为主,很可能是扫描器在遍历路径。可以进一步看该 IP 都在请求什么:

grep '203.0.113.10' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -n 20

上面命令中的 IP 只是示例,实际使用时替换为日志中真实出现的 IP。

四、按响应时间排序,定位最慢的请求

假设日志最后一列是 $request_time,按耗时倒序取前 20 条:

awk '{print $NF, $7, $9}' /var/log/nginx/access.log | sort -nr | head -n 20

$NF 表示每行的最后一个字段,也就是耗时;$7 是请求路径,$9 是状态码。如果最慢的请求集中在某一个接口,问题大概率在该接口的后端逻辑或数据库查询上。

也可以只统计耗时超过 1 秒的请求数量:

awk '$NF > 1' /var/log/nginx/access.log | wc -l

五、统计各接口的请求量与平均耗时

把同一接口的请求聚合起来,算出请求数与平均耗时:

awk '{sum[$7]+=$NF; count[$7]++} END {for (u in count) printf "%s %d %.3f\n", u, count[u], sum[u]/count[u]}' /var/log/nginx/access.log | sort -k2 -nr | head -n 20

输出的三列分别是接口路径、请求数、平均耗时(秒)。请求量大且平均耗时也高的接口,就是优先优化的对象。

六、按时间段圈定故障窗口

知道故障大概发生在 10:00 到 10:30 之间时,可以先按时间过滤再分析:

awk '$4 >= "[10/Nov/2026:10:00:00" && $4 <= "[10/Nov/2026:10:30:00"' /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c | sort -nr

时间格式是日志里 $4 字段的格式,例如 [10/Nov/2026:10:00:00,日期部分要按实际日志填写。如果日志已经按天轮转(access.log.1、access.log.2.gz),需要把对应日期的文件一起作为输入,压缩文件先用 zcat 解开。

七、把常用分析保存为小脚本

每次出问题都现敲命令容易出错,可以把上面的命令写进一个脚本,例如 ~/bin/nginx-log-check.sh,接受日志路径作为参数,依次输出状态码分布、Top IP 与最慢请求。脚本本身不做任何封禁或修改操作,只做只读分析,排查结束后再根据结论决定是否调整配置或封禁 IP。

八、注意事项

  1. 日志轮转后旧文件会被压缩或删除,排查时先确认故障时间段对应的日志文件还在不在。
  2. 日志可能包含用户真实的访问路径与参数,分析结果不要直接发到公开渠道,涉及敏感信息要先脱敏。
  3. awk 的字段编号依赖日志格式,改了 log_format 就要同步改字段号,先用 head 看一行再写命令。
  4. 本文的命令只读日志,不会修改 Nginx 配置或重启服务,适合在生产服务器上先做初步定位。

掌握这套方法后,大多数“网站突然变慢”“某个接口报错多”的问题,都能在几分钟内从日志里找到方向,再决定是优化接口、扩容还是处理异常来源。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。