Nginx查找耗时的接口
# grep 是筛选的域名 awk中的$5是判断的状态码 sort中的15是指的upstream_response_time 当然也可以统计request_time的时间
#!/bin/bash
# 默认配置
LOG_FILE="/var/log/nginx/access.log" # Nginx日志文件路径
DOMAIN="" # 筛选的域名(空表示所有)
STATUS_CODE="200" # 状态码(空表示所有)
TOP_N=10 # 显示前N条
TIME_FIELD="upstream_response_time" # 统计的时间字段(request_time/upstream_response_time)
TIME_THRESHOLD=0 # 最小耗时阈值(秒,0表示不限制)
# 显示帮助信息
usage() {
echo "用法: $0 [选项]"
echo "分析Nginx日志中耗时较长的接口"
echo "选项:"
echo " -f <日志文件> 指定Nginx日志文件路径(默认: $LOG_FILE)"
echo " -d <域名> 筛选特定域名(如 zhhll.com.cn)"
echo " -s <状态码> 筛选特定状态码(如 200, 500)"
echo " -n <数量> 显示前N条记录(默认: $TOP_N)"
echo " -t <时间字段> 时间字段(request_time/upstream_response_time, 默认: $TIME_FIELD)"
echo " -T <阈值> 最小耗时阈值(秒,默认: $TIME_THRESHOLD)"
echo " -h 显示帮助信息"
exit 1
}
# 解析命令行参数
while getopts "f:d:s:n:t:T:h" opt; do
case $opt in
f) LOG_FILE="$OPTARG" ;;
d) DOMAIN="$OPTARG" ;;
s) STATUS_CODE="$OPTARG" ;;
n) TOP_N="$OPTARG" ;;
t) TIME_FIELD="$OPTARG" ;;
T) TIME_THRESHOLD="$OPTARG" ;;
h) usage ;;
*) usage ;;
esac
done
# 验证时间字段合法性
if [ "$TIME_FIELD" != "request_time" ] && [ "$TIME_FIELD" != "upstream_response_time" ]; then
echo "错误: 时间字段必须是 request_time 或 upstream_response_time"
exit 1
fi
# 确定时间字段在日志中的列数(根据实际log_format调整)
# 以下假设为默认combined日志格式扩展,包含upstream_response_time
# 请根据实际日志格式修改字段索引
if [ "$TIME_FIELD" = "request_time" ]; then
TIME_COLUMN=10 # 假设request_time在第10列
else
TIME_COLUMN=15 # 假设upstream_response_time在第15列
fi
# 构建筛选条件
FILTER=""
if [ -n "$DOMAIN" ]; then
FILTER="$FILTER | grep '$DOMAIN'"
fi
if [ -n "$STATUS_CODE" ]; then
# 假设状态码在第9列(根据实际日志格式调整)
FILTER="$FILTER | awk '\$9 == $STATUS_CODE {print \$0}'"
fi
# 执行分析命令
echo "分析日志: $LOG_FILE"
echo "筛选条件: 域名=$DOMAIN, 状态码=$STATUS_CODE, 时间字段=$TIME_FIELD, 最小耗时=$TIME_THRESHOLD秒"
echo "----------------------------------------"
eval "cat $LOG_FILE $FILTER | awk -v col=$TIME_COLUMN -v threshold=$TIME_THRESHOLD '
\$col + 0 >= threshold { # 转换为数字比较,过滤小于阈值的记录
print \$col \"\t\" \$7 \"\t\" \$9 # 输出: 耗时 接口路径 状态码
}
' | sort -k1,1nr | head -n $TOP_N"
echo "----------------------------------------"
echo "字段说明: [耗时(秒)] [接口路径] [状态码]"
使用示例
./nginx_slow_apis.sh -d zhhll.com.cn -T 0.5 -n 20
./nginx_slow_apis.sh -s 500 -t request_time
./nginx_slow_apis.sh -f /var/log/nginx/access_8080.log -n 15
注意事项
- 日志格式适配
脚本中默认的字段索引(如状态码在第 9 列)基于常见的 Nginx 日志格式,需根据实际 log_format 配置调整 TIME_COLUMN 和状态码列的数值。
- 大日志处理
对于超大日志文件,建议先通过 tail 取最近数据,或使用 awk 直接处理(避免 cat | grep 的管道开销)。
- 自动化分析
可将脚本添加到定时任务,定期生成慢接口报告,及时发现性能退化问题。